/// weightを付与して、matrixを適用する static void FixNoSkinJoints(SpanLike <SkinJoints> joints, SpanLike <Vector4> weights, int jointIndex, SpanLike <Vector3> positions, SpanLike <Vector3> normals, Matrix4x4 matrix) { for (int i = 0; i < joints.Length; ++i) { var j = new SkinJoints { Joint0 = (ushort)jointIndex }; joints[i] = j; var w = new Vector4 { X = 1.0f, }; weights[i] = w; { // position var src = positions[i]; var dst = Vector4.Transform(new Vector4(src, 1), matrix); positions[i] = new Vector3(dst.X, dst.Y, dst.Z); } { // normal var src = normals[i]; var dst = Vector4.Transform(new Vector4(src, 0), matrix); normals[i] = new Vector3(dst.X, dst.Y, dst.Z); } } }
public static void Write(byte[] bytes, int i, SkinJoints value) { Write(bytes, i, value.Joint0); Write(bytes, i + 2, value.Joint1); Write(bytes, i + 4, value.Joint2); Write(bytes, i + 6, value.Joint3); }
public void Apply(VertexBuffer vertexBuffer, Span <Vector3> dstPosition, Span <Vector3> dstNormal) { var jointsBuffer = vertexBuffer.Joints; var joints = (jointsBuffer != null || jointsBuffer.Count == 0) ? jointsBuffer.GetSpan <SkinJoints>() : new SkinJoints[vertexBuffer.Count].AsSpan() // when MorphTarget only ; var weightsBuffer = vertexBuffer.Weights; var weights = (weightsBuffer != null || weightsBuffer.Count == 0) ? weightsBuffer.GetSpan <Vector4>() : new Vector4[vertexBuffer.Count].AsSpan() // when MorphTarget only ; var positionBuffer = vertexBuffer.Positions; var position = positionBuffer.GetSpan <Vector3>(); bool useNormal = false; if (!dstNormal.IsEmpty) { useNormal = vertexBuffer.Normals != null && dstNormal.Length == dstPosition.Length; } for (int i = 0; i < position.Length; ++i) { var j = joints[i]; var w = weights[i]; var sum = (w.X + w.Y + w.Z + w.W); float factor; if (sum > 0) { factor = 1.0f / sum; } else { factor = 1.0f; j = new SkinJoints(m_indexOfRoot, 0, 0, 0); w = new Vector4(1, 0, 0, 0); } if (j.Joint0 == ushort.MaxValue) { w.X = 0; } if (j.Joint1 == ushort.MaxValue) { w.Y = 0; } if (j.Joint2 == ushort.MaxValue) { w.Z = 0; } if (j.Joint3 == ushort.MaxValue) { w.W = 0; } { var src = new Vector4(position[i], 1); // 位置ベクトル var dst = Vector4.Zero; if (w.X > 0) { dst += Vector4.Transform(src, m_matrices[j.Joint0]) * w.X * factor; } if (w.Y > 0) { dst += Vector4.Transform(src, m_matrices[j.Joint1]) * w.Y * factor; } if (w.Z > 0) { dst += Vector4.Transform(src, m_matrices[j.Joint2]) * w.Z * factor; } if (w.W > 0) { dst += Vector4.Transform(src, m_matrices[j.Joint3]) * w.W * factor; } dstPosition[i] = new Vector3(dst.X, dst.Y, dst.Z); } if (useNormal) { var normalBuffer = vertexBuffer.Normals; var normal = normalBuffer != null?normalBuffer.GetSpan <Vector3>() : dstNormal; var src = new Vector4(normal[i], 0); // 方向ベクトル var dst = Vector4.Zero; if (w.X > 0) { dst += Vector4.Transform(src, m_matrices[j.Joint0]) * w.X * factor; } if (w.Y > 0) { dst += Vector4.Transform(src, m_matrices[j.Joint1]) * w.Y * factor; } if (w.Z > 0) { dst += Vector4.Transform(src, m_matrices[j.Joint2]) * w.Z * factor; } if (w.W > 0) { dst += Vector4.Transform(src, m_matrices[j.Joint3]) * w.W * factor; } dstNormal[i] = new Vector3(dst.X, dst.Y, dst.Z); } } }
public void Apply(INativeArrayManager arrayManager, VertexBuffer vertexBuffer, NativeArray <Vector3> dstPosition, NativeArray <Vector3> dstNormal) { var jointsBuffer = vertexBuffer.Joints; var joints = (jointsBuffer != null || jointsBuffer.Count == 0) ? jointsBuffer.GetAsSkinJointsArray() : arrayManager.CreateNativeArray <SkinJoints>(vertexBuffer.Count) // when MorphTarget only ; var weightsBuffer = vertexBuffer.Weights; var weights = (weightsBuffer != null || weightsBuffer.Count == 0) ? weightsBuffer.GetAsVector4Array() : arrayManager.CreateNativeArray <Vector4>(vertexBuffer.Count) // when MorphTarget only ; var positionBuffer = vertexBuffer.Positions; var position = positionBuffer.Bytes.Reinterpret <Vector3>(1); bool useNormal = false; if (dstNormal.Length > 0) { useNormal = vertexBuffer.Normals != null && dstNormal.Length == dstPosition.Length; } for (int i = 0; i < position.Length; ++i) { var j = joints[i]; var w = weights[i]; var sum = (w.x + w.y + w.z + w.w); float factor; if (sum > 0) { factor = 1.0f / sum; } else { factor = 1.0f; j = new SkinJoints(m_indexOfRoot, 0, 0, 0); w = new Vector4(1, 0, 0, 0); } if (j.Joint0 == ushort.MaxValue) { w.x = 0; } if (j.Joint1 == ushort.MaxValue) { w.y = 0; } if (j.Joint2 == ushort.MaxValue) { w.z = 0; } if (j.Joint3 == ushort.MaxValue) { w.w = 0; } { var src = position[i]; // 位置ベクトル var dst = Vector3.zero; if (w.x > 0) { dst += m_matrices[j.Joint0].MultiplyPoint(src) * w.x * factor; } if (w.y > 0) { dst += m_matrices[j.Joint1].MultiplyPoint(src) * w.y * factor; } if (w.z > 0) { dst += m_matrices[j.Joint2].MultiplyPoint(src) * w.z * factor; } if (w.w > 0) { dst += m_matrices[j.Joint3].MultiplyPoint(src) * w.w * factor; } dstPosition[i] = new Vector3(dst.x, dst.y, dst.z); } if (useNormal) { var normalBuffer = vertexBuffer.Normals; var normal = normalBuffer != null?normalBuffer.Bytes.Reinterpret <Vector3>(1) : dstNormal; var src = normal[i]; // 方向ベクトル var dst = Vector3.zero; if (w.x > 0) { dst += m_matrices[j.Joint0].MultiplyVector(src) * w.x * factor; } if (w.y > 0) { dst += m_matrices[j.Joint1].MultiplyVector(src) * w.y * factor; } if (w.z > 0) { dst += m_matrices[j.Joint2].MultiplyVector(src) * w.z * factor; } if (w.w > 0) { dst += m_matrices[j.Joint3].MultiplyVector(src) * w.w * factor; } dstNormal[i] = new Vector3(dst.x, dst.y, dst.z); } } }