// Taken from: http://answers.unity3d.com/comments/190515/view.html // Official support for Mesh.RecalculateTangents should be coming in 5.6 // https://feedback.unity3d.com/suggestions/recalculatetangents /*private MeshPrimitiveAttributes CalculateAndSetTangents(MeshPrimitiveAttributes attributes) * { * var triangleCount = attributes.Triangles.Length; * var vertexCount = attributes.Vertices.Length; * * var tan1 = new Vector3[vertexCount]; * var tan2 = new Vector3[vertexCount]; * * attributes.Tangents = new Vector4[vertexCount]; * * for (long a = 0; a < triangleCount; a += 3) * { * long i1 = attributes.Triangles[a + 0]; * long i2 = attributes.Triangles[a + 1]; * long i3 = attributes.Triangles[a + 2]; * * var v1 = attributes.Vertices[i1]; * var v2 = attributes.Vertices[i2]; * var v3 = attributes.Vertices[i3]; * * var w1 = attributes.Uv[i1]; * var w2 = attributes.Uv[i2]; * var w3 = attributes.Uv[i3]; * * var x1 = v2.X - v1.X; * var x2 = v3.X - v1.X; * var y1 = v2.Y - v1.Y; * var y2 = v3.Y - v1.Y; * var z1 = v2.Z - v1.Z; * var z2 = v3.Z - v1.Z; * * var s1 = w2.X - w1.X; * var s2 = w3.X - w1.X; * var t1 = w2.Y - w1.Y; * var t2 = w3.Y - w1.Y; * * var r = 1.0f / (s1 * t2 - s2 * t1); * * var sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); * var tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); * * tan1[i1] += sdir; * tan1[i2] += sdir; * tan1[i3] += sdir; * * tan2[i1] += tdir; * tan2[i2] += tdir; * tan2[i3] += tdir; * } * * * for (long a = 0; a < vertexCount; ++a) * { * var n = attributes.Normals[a]; * var t = tan1[a]; * * Vector3.OrthoNormalize(ref n, ref t); * * attributes.Tangents[a].X = t.X; * attributes.Tangents[a].Y = t.Y; * attributes.Tangents[a].Z = t.Z; * * attributes.Tangents[a].W = (Vector3.Dot(Vector3.Cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f; * } * * return attributes; * }*/ public static MeshPrimitive Deserialize(GLTFRoot root, JsonReader reader) { var primitive = new MeshPrimitive(); while (reader.Read() && reader.TokenType == JsonToken.PropertyName) { var curProp = reader.Value.ToString(); switch (curProp) { case "attributes": primitive.Attributes = reader.ReadAsDictionary(() => new AccessorId { Id = reader.ReadAsInt32().Value, Root = root }); break; case "indices": primitive.Indices = AccessorId.Deserialize(root, reader); break; case "material": primitive.Material = MaterialId.Deserialize(root, reader); break; case "mode": primitive.Mode = (DrawMode)reader.ReadAsInt32().Value; break; case "targets": primitive.Targets = reader.ReadList(() => { return(reader.ReadAsDictionary(() => new AccessorId { Id = reader.ReadAsInt32().Value, Root = root }, skipStartObjectRead: true)); }); break; default: primitive.DefaultPropertyDeserializer(root, reader); break; } } return(primitive); }
public MeshPrimitive(MeshPrimitive meshPrimitive, GLTFRoot gltfRoot) : base(meshPrimitive) { if (meshPrimitive == null) { return; } if (meshPrimitive.Attributes != null) { Attributes = new Dictionary <string, AccessorId>(meshPrimitive.Attributes.Count); foreach (KeyValuePair <string, AccessorId> attributeKeyValuePair in meshPrimitive.Attributes) { Attributes[attributeKeyValuePair.Key] = new AccessorId(attributeKeyValuePair.Value, gltfRoot); } } if (meshPrimitive.Indices != null) { Indices = new AccessorId(meshPrimitive.Indices, gltfRoot); } if (meshPrimitive.Material != null) { Material = new MaterialId(meshPrimitive.Material, gltfRoot); } Mode = meshPrimitive.Mode; if (meshPrimitive.Targets != null) { Targets = new List <Dictionary <string, AccessorId> >(meshPrimitive.Targets.Count); foreach (Dictionary <string, AccessorId> targetToCopy in meshPrimitive.Targets) { Dictionary <string, AccessorId> target = new Dictionary <string, AccessorId>(targetToCopy.Count); foreach (KeyValuePair <string, AccessorId> targetKeyValuePair in targetToCopy) { target[targetKeyValuePair.Key] = new AccessorId(targetKeyValuePair.Value, gltfRoot); } Targets.Add(target); } } if (meshPrimitive.TargetNames != null) { TargetNames = new List <string>(meshPrimitive.TargetNames); } }
// Taken from: http://answers.unity3d.com/comments/190515/view.html // Official support for Mesh.RecalculateTangents should be coming in 5.6 // https://feedback.unity3d.com/suggestions/recalculatetangents /*private MeshPrimitiveAttributes CalculateAndSetTangents(MeshPrimitiveAttributes attributes) * { * var triangleCount = attributes.Triangles.Length; * var vertexCount = attributes.Vertices.Length; * * var tan1 = new Vector3[vertexCount]; * var tan2 = new Vector3[vertexCount]; * * attributes.Tangents = new Vector4[vertexCount]; * * for (long a = 0; a < triangleCount; a += 3) * { * long i1 = attributes.Triangles[a + 0]; * long i2 = attributes.Triangles[a + 1]; * long i3 = attributes.Triangles[a + 2]; * * var v1 = attributes.Vertices[i1]; * var v2 = attributes.Vertices[i2]; * var v3 = attributes.Vertices[i3]; * * var w1 = attributes.Uv[i1]; * var w2 = attributes.Uv[i2]; * var w3 = attributes.Uv[i3]; * * var x1 = v2.X - v1.X; * var x2 = v3.X - v1.X; * var y1 = v2.Y - v1.Y; * var y2 = v3.Y - v1.Y; * var z1 = v2.Z - v1.Z; * var z2 = v3.Z - v1.Z; * * var s1 = w2.X - w1.X; * var s2 = w3.X - w1.X; * var t1 = w2.Y - w1.Y; * var t2 = w3.Y - w1.Y; * * var r = 1.0f / (s1 * t2 - s2 * t1); * * var sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); * var tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); * * tan1[i1] += sdir; * tan1[i2] += sdir; * tan1[i3] += sdir; * * tan2[i1] += tdir; * tan2[i2] += tdir; * tan2[i3] += tdir; * } * * * for (long a = 0; a < vertexCount; ++a) * { * var n = attributes.Normals[a]; * var t = tan1[a]; * * Vector3.OrthoNormalize(ref n, ref t); * * attributes.Tangents[a].X = t.X; * attributes.Tangents[a].Y = t.Y; * attributes.Tangents[a].Z = t.Z; * * attributes.Tangents[a].W = (Vector3.Dot(Vector3.Cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f; * } * * return attributes; * }*/ public static MeshPrimitive Deserialize(GLTFRoot root, JsonReader reader) { var primitive = new MeshPrimitive(); while (reader.Read() && reader.TokenType == JsonToken.PropertyName) { var curProp = reader.Value.ToString(); switch (curProp) { case "attributes": primitive.Attributes = reader.ReadAsDictionary(() => new AccessorId { Id = reader.ReadAsInt32().Value, Root = root }); break; case "indices": primitive.Indices = AccessorId.Deserialize(root, reader); break; case "material": primitive.Material = MaterialId.Deserialize(root, reader); break; case "mode": primitive.Mode = (DrawMode)reader.ReadAsInt32().Value; break; case "targets": primitive.Targets = reader.ReadList(() => { return(reader.ReadAsDictionary(() => new AccessorId { Id = reader.ReadAsInt32().Value, Root = root }, skipStartObjectRead: true)); }); break; case "extras": // GLTF does not support morph target names, serialize in extras for now // https://github.com/KhronosGroup/glTF/issues/1036 if (reader.Read() && reader.TokenType == JsonToken.StartObject) { while (reader.Read() && reader.TokenType == JsonToken.PropertyName) { var extraProperty = reader.Value.ToString(); switch (extraProperty) { case "targetNames": primitive.TargetNames = reader.ReadStringList(); break; } } } break; default: primitive.DefaultPropertyDeserializer(root, reader); break; } } return(primitive); }
public MaterialId(MaterialId id, GLTFRoot newRoot) : base(id, newRoot) { }