public VertexInfo lerp (final VertexInfo target, float alpha) { if (hasPosition && target.hasPosition) position.lerp(target.position, alpha); if (hasNormal && target.hasNormal) normal.lerp(target.normal, alpha); if (hasColor && target.hasColor) color.lerp(target.color, alpha); if (hasUV && target.hasUV) uv.lerp(target.uv, alpha); return this; } }
public VertexInfo lerp (final VertexInfo target, float alpha) { if (hasPosition && target.hasPosition) position.lerp(target.position, alpha); if (hasNormal && target.hasNormal) normal.lerp(target.normal, alpha); if (hasColor && target.hasColor) color.lerp(target.color, alpha); if (hasUV && target.hasUV) uv.lerp(target.uv, alpha); return this; } }
@Override public Vector3 interpolate (Vector3 target, float alpha, Interpolation interpolator) { return lerp(target, interpolator.apply(0f, 1f, alpha)); }
@Override public Vector3 interpolate (Vector3 target, float alpha, Interpolation interpolator) { return lerp(target, interpolator.apply(0f, 1f, alpha)); }
public Vector3 getPositionAt (Vector3 out, int x, int y) { final float dx = (float)x / (float)(width - 1); final float dy = (float)y / (float)(height - 1); final float a = data[y * width + x]; out.set(corner00).lerp(corner10, dx).lerp(tmpV1.set(corner01).lerp(corner11, dx), dy); out.add(tmpV1.set(magnitude).scl(a)); return out; }
/** Spherically interpolates between this vector and the target vector by alpha which is in the range [0,1]. The result is * stored in this vector. * * @param target The target vector * @param alpha The interpolation coefficient * @return This vector for chaining. */ public Vector3 slerp (final Vector3 target, float alpha) { final float dot = dot(target); // If the inputs are too close for comfort, simply linearly interpolate. if (dot > 0.9995 || dot < -0.9995) return lerp(target, alpha); // theta0 = angle between input vectors final float theta0 = (float)Math.acos(dot); // theta = angle between this vector and result final float theta = theta0 * alpha; final float st = (float)Math.sin(theta); final float tx = target.x - x * dot; final float ty = target.y - y * dot; final float tz = target.z - z * dot; final float l2 = tx * tx + ty * ty + tz * tz; final float dl = st * ((l2 < 0.0001f) ? 1f : 1f / (float)Math.sqrt(l2)); return scl((float)Math.cos(theta)).add(tx * dl, ty * dl, tz * dl).nor(); }
/** Spherically interpolates between this vector and the target vector by alpha which is in the range [0,1]. The result is * stored in this vector. * * @param target The target vector * @param alpha The interpolation coefficient * @return This vector for chaining. */ public Vector3 slerp (final Vector3 target, float alpha) { final float dot = dot(target); // If the inputs are too close for comfort, simply linearly interpolate. if (dot > 0.9995 || dot < -0.9995) return lerp(target, alpha); // theta0 = angle between input vectors final float theta0 = (float)Math.acos(dot); // theta = angle between this vector and result final float theta = theta0 * alpha; final float st = (float)Math.sin(theta); final float tx = target.x - x * dot; final float ty = target.y - y * dot; final float tz = target.z - z * dot; final float l2 = tx * tx + ty * ty + tz * tz; final float dl = st * ((l2 < 0.0001f) ? 1f : 1f / (float)Math.sqrt(l2)); return scl((float)Math.cos(theta)).add(tx * dl, ty * dl, tz * dl).nor(); }
/** Does not set the normal member! */ protected VertexInfo getVertexAt (final VertexInfo out, int x, int y) { final float dx = (float)x / (float)(width - 1); final float dy = (float)y / (float)(height - 1); final float a = data[y * width + x]; out.position.set(corner00).lerp(corner10, dx).lerp(tmpV1.set(corner01).lerp(corner11, dx), dy); out.position.add(tmpV1.set(magnitude).scl(a)); out.color.set(color00).lerp(color10, dx).lerp(tmpC.set(color01).lerp(color11, dx), dy); out.uv.set(dx, dy).scl(uvScale).add(uvOffset); return out; }
private final static Vector3 getScalingAtTime (final NodeAnimation nodeAnim, final float time, final Vector3 out) { if (nodeAnim.scaling == null) return out.set(nodeAnim.node.scale); if (nodeAnim.scaling.size == 1) return out.set(nodeAnim.scaling.get(0).value); int index = getFirstKeyframeIndexAtTime(nodeAnim.scaling, time); final NodeKeyframe firstKeyframe = nodeAnim.scaling.get(index); out.set((Vector3)firstKeyframe.value); if (++index < nodeAnim.scaling.size) { final NodeKeyframe<Vector3> secondKeyframe = nodeAnim.scaling.get(index); final float t = (time - firstKeyframe.keytime) / (secondKeyframe.keytime - firstKeyframe.keytime); out.lerp(secondKeyframe.value, t); } return out; }
private final static Vector3 getTranslationAtTime (final NodeAnimation nodeAnim, final float time, final Vector3 out) { if (nodeAnim.translation == null) return out.set(nodeAnim.node.translation); if (nodeAnim.translation.size == 1) return out.set(nodeAnim.translation.get(0).value); int index = getFirstKeyframeIndexAtTime(nodeAnim.translation, time); final NodeKeyframe firstKeyframe = nodeAnim.translation.get(index); out.set((Vector3)firstKeyframe.value); if (++index < nodeAnim.translation.size) { final NodeKeyframe<Vector3> secondKeyframe = nodeAnim.translation.get(index); final float t = (time - firstKeyframe.keytime) / (secondKeyframe.keytime - firstKeyframe.keytime); out.lerp(secondKeyframe.value, t); } return out; }
private final static Vector3 getTranslationAtTime (final NodeAnimation nodeAnim, final float time, final Vector3 out) { if (nodeAnim.translation == null) return out.set(nodeAnim.node.translation); if (nodeAnim.translation.size == 1) return out.set(nodeAnim.translation.get(0).value); int index = getFirstKeyframeIndexAtTime(nodeAnim.translation, time); final NodeKeyframe firstKeyframe = nodeAnim.translation.get(index); out.set((Vector3)firstKeyframe.value); if (++index < nodeAnim.translation.size) { final NodeKeyframe<Vector3> secondKeyframe = nodeAnim.translation.get(index); final float t = (time - firstKeyframe.keytime) / (secondKeyframe.keytime - firstKeyframe.keytime); out.lerp(secondKeyframe.value, t); } return out; }
private final static Vector3 getScalingAtTime (final NodeAnimation nodeAnim, final float time, final Vector3 out) { if (nodeAnim.scaling == null) return out.set(nodeAnim.node.scale); if (nodeAnim.scaling.size == 1) return out.set(nodeAnim.scaling.get(0).value); int index = getFirstKeyframeIndexAtTime(nodeAnim.scaling, time); final NodeKeyframe firstKeyframe = nodeAnim.scaling.get(index); out.set((Vector3)firstKeyframe.value); if (++index < nodeAnim.scaling.size) { final NodeKeyframe<Vector3> secondKeyframe = nodeAnim.scaling.get(index); final float t = (time - firstKeyframe.keytime) / (secondKeyframe.keytime - firstKeyframe.keytime); out.lerp(secondKeyframe.value, t); } return out; }
/** Add a box. Requires GL_POINTS, GL_LINES or GL_TRIANGLES primitive type. */ public static void build (MeshPartBuilder builder, Vector3 corner000, Vector3 corner010, Vector3 corner100, Vector3 corner110, Vector3 corner001, Vector3 corner011, Vector3 corner101, Vector3 corner111) { if ((builder.getAttributes().getMask() & (Usage.Normal | Usage.BiNormal | Usage.Tangent | Usage.TextureCoordinates)) == 0) { build(builder, vertTmp1.set(corner000, null, null, null), vertTmp2.set(corner010, null, null, null), vertTmp3.set(corner100, null, null, null), vertTmp4.set(corner110, null, null, null), vertTmp5.set(corner001, null, null, null), vertTmp6.set(corner011, null, null, null), vertTmp7.set(corner101, null, null, null), vertTmp8.set(corner111, null, null, null)); } else { builder.ensureVertices(24); builder.ensureRectangleIndices(6); Vector3 nor = tmpV1.set(corner000).lerp(corner110, 0.5f).sub(tmpV2.set(corner001).lerp(corner111, 0.5f)).nor(); builder.rect(corner000, corner010, corner110, corner100, nor); builder.rect(corner011, corner001, corner101, corner111, nor.scl(-1)); nor = tmpV1.set(corner000).lerp(corner101, 0.5f).sub(tmpV2.set(corner010).lerp(corner111, 0.5f)).nor(); builder.rect(corner001, corner000, corner100, corner101, nor); builder.rect(corner010, corner011, corner111, corner110, nor.scl(-1)); nor = tmpV1.set(corner000).lerp(corner011, 0.5f).sub(tmpV2.set(corner100).lerp(corner111, 0.5f)).nor(); builder.rect(corner001, corner011, corner010, corner000, nor); builder.rect(corner100, corner110, corner111, corner101, nor.scl(-1)); } }
/** Add a box. Requires GL_POINTS, GL_LINES or GL_TRIANGLES primitive type. */ public static void build (MeshPartBuilder builder, Vector3 corner000, Vector3 corner010, Vector3 corner100, Vector3 corner110, Vector3 corner001, Vector3 corner011, Vector3 corner101, Vector3 corner111) { if ((builder.getAttributes().getMask() & (Usage.Normal | Usage.BiNormal | Usage.Tangent | Usage.TextureCoordinates)) == 0) { build(builder, vertTmp1.set(corner000, null, null, null), vertTmp2.set(corner010, null, null, null), vertTmp3.set(corner100, null, null, null), vertTmp4.set(corner110, null, null, null), vertTmp5.set(corner001, null, null, null), vertTmp6.set(corner011, null, null, null), vertTmp7.set(corner101, null, null, null), vertTmp8.set(corner111, null, null, null)); } else { builder.ensureVertices(24); builder.ensureRectangleIndices(6); Vector3 nor = tmpV1.set(corner000).lerp(corner110, 0.5f).sub(tmpV2.set(corner001).lerp(corner111, 0.5f)).nor(); builder.rect(corner000, corner010, corner110, corner100, nor); builder.rect(corner011, corner001, corner101, corner111, nor.scl(-1)); nor = tmpV1.set(corner000).lerp(corner101, 0.5f).sub(tmpV2.set(corner010).lerp(corner111, 0.5f)).nor(); builder.rect(corner001, corner000, corner100, corner101, nor); builder.rect(corner010, corner011, corner111, corner110, nor.scl(-1)); nor = tmpV1.set(corner000).lerp(corner011, 0.5f).sub(tmpV2.set(corner100).lerp(corner111, 0.5f)).nor(); builder.rect(corner001, corner011, corner010, corner000, nor); builder.rect(corner100, corner110, corner111, corner101, nor.scl(-1)); } }
private void updateSharp () { final int w = width - 1; final int h = height - 1; for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { final int c00 = (y * 2 * w + x * 2); final int c10 = c00 + 1; final int c01 = c00 + w * 2; final int c11 = c10 + w * 2; VertexInfo v00 = getVertexAt(vertex00, x, y); VertexInfo v10 = getVertexAt(vertex10, x + 1, y); VertexInfo v01 = getVertexAt(vertex01, x, y + 1); VertexInfo v11 = getVertexAt(vertex11, x + 1, y + 1); v01.normal.set(v01.position).sub(v00.position).nor().crs(tmpV1.set(v11.position).sub(v01.position).nor()); v10.normal.set(v10.position).sub(v11.position).nor().crs(tmpV1.set(v00.position).sub(v10.position).nor()); v00.normal.set(v01.normal).lerp(v10.normal, .5f); v11.normal.set(v00.normal); setVertex(c00, v00); setVertex(c10, v10); setVertex(c01, v01); setVertex(c11, v11); } } mesh.setVertices(vertices); }
public VertexInfo lerp (final VertexInfo target, float alpha) { if (hasPosition && target.hasPosition) position.lerp(target.position, alpha); if (hasNormal && target.hasNormal) normal.lerp(target.normal, alpha); if (hasColor && target.hasColor) color.lerp(target.color, alpha); if (hasUV && target.hasUV) uv.lerp(target.uv, alpha); return this; } }
private final static Vector3 getScalingAtTime (final NodeAnimation nodeAnim, final float time, final Vector3 out) { if (nodeAnim.scaling == null) return out.set(nodeAnim.node.scale); if (nodeAnim.scaling.size == 1) return out.set(nodeAnim.scaling.get(0).value); int index = getFirstKeyframeIndexAtTime(nodeAnim.scaling, time); final NodeKeyframe firstKeyframe = nodeAnim.scaling.get(index); out.set((Vector3)firstKeyframe.value); if (++index < nodeAnim.scaling.size) { final NodeKeyframe<Vector3> secondKeyframe = nodeAnim.scaling.get(index); final float t = (time - firstKeyframe.keytime) / (secondKeyframe.keytime - firstKeyframe.keytime); out.lerp(secondKeyframe.value, t); } return out; }
private final static Vector3 getTranslationAtTime (final NodeAnimation nodeAnim, final float time, final Vector3 out) { if (nodeAnim.translation == null) return out.set(nodeAnim.node.translation); if (nodeAnim.translation.size == 1) return out.set(nodeAnim.translation.get(0).value); int index = getFirstKeyframeIndexAtTime(nodeAnim.translation, time); final NodeKeyframe firstKeyframe = nodeAnim.translation.get(index); out.set((Vector3)firstKeyframe.value); if (++index < nodeAnim.translation.size) { final NodeKeyframe<Vector3> secondKeyframe = nodeAnim.translation.get(index); final float t = (time - firstKeyframe.keytime) / (secondKeyframe.keytime - firstKeyframe.keytime); out.lerp(secondKeyframe.value, t); } return out; }