public static string ToJson(this glTFPrimitives self) { var f = new JsonFormatter(); GltfSerializer.Serialize_gltf_meshes__primitives_ITEM(f, self); return(f.ToString()); }
public static bool HasSameVertexBuffer(this glTFPrimitives lhs, glTFPrimitives rhs) { if (lhs.attributes.POSITION != rhs.attributes.POSITION) { return(false); } if (lhs.attributes.NORMAL != rhs.attributes.NORMAL) { return(false); } if (lhs.attributes.TEXCOORD_0 != rhs.attributes.TEXCOORD_0) { return(false); } if (lhs.attributes.TEXCOORD_1 != rhs.attributes.TEXCOORD_1) { return(false); } if (lhs.attributes.COLOR_0 != rhs.attributes.COLOR_0) { return(false); } if (lhs.attributes.WEIGHTS_0 != rhs.attributes.WEIGHTS_0) { return(false); } if (lhs.attributes.JOINTS_0 != rhs.attributes.JOINTS_0) { return(false); } return(true); }
public static SkinningInfo Create(GltfData data, glTFMesh mesh, glTFPrimitives primitives) { var hasMorphTarget = HasMorphTarget(mesh); var positions = data.GLTF.accessors[primitives.attributes.POSITION]; var skinning = new SkinningInfo { Joints = primitives.GetJoints(data, positions.count), Weights = primitives.GetWeights(data, positions.count), }; if (skinning.Joints != null) { // use SkinnedMeshRenderer return(skinning); } else if (!hasMorphTarget) { // use MeshRenderer return(skinning); } else { // use SkinnedMeshRenderer without boneWeight. // https://github.com/vrm-c/UniVRM/issues/1675 return(new SkinningInfo { ShouldSetRendererNodeAsBone = true, Joints = _ => (0, 0, 0, 0), Weights = _ => (1, 0, 0, 0), // assign weight 1 });
static Mesh FromGltf(Vrm10ImportData storage, glTFMesh x, glTFPrimitives primitive, bool isShared) { var mesh = new Mesh((TopologyType)primitive.mode) { VertexBuffer = primitive.attributes.FromGltf(storage) }; if (isShared) { // create joined index buffer mesh.IndexBuffer = storage.CreateAccessor(x.primitives.Select(y => y.indices).ToArray()); } else { mesh.IndexBuffer = storage.CreateAccessor(primitive.indices); } if (mesh.IndexBuffer == null) { var indices = Enumerable.Range(0, mesh.VertexBuffer.Count).ToArray(); var na = storage.Data.NativeArrayManager.CreateNativeArray(indices); mesh.IndexBuffer = new BufferAccessor(storage.Data.NativeArrayManager, na.Reinterpret <byte>(4), AccessorValueType.UNSIGNED_INT, AccessorVectorType.SCALAR, na.Length); } { gltf_mesh_extras_targetNames.TryGet(x, out List <string> targetNames); for (int i = 0; i < primitive.targets.Count; ++i) { var gltfTarget = primitive.targets[i]; string targetName = null; { targetName = targetNames[i]; } var target = new MorphTarget(targetName) { VertexBuffer = gltfTarget.FromGltf(storage) }; // validate count foreach (var kv in target.VertexBuffer) { if (kv.Value.Count != mesh.VertexBuffer.Count) { throw new Exception(); } } mesh.MorphTargets.Add(target); } } return(mesh); }
bool HasSameBuffer(glTFPrimitives lhs, glTFPrimitives rhs) { { var l = GLTF.accessors[lhs.indices]; var r = GLTF.accessors[rhs.indices]; if (l.componentType != r.componentType) { return(false); } if (l.type != r.type) { return(false); } if (l.bufferView != r.bufferView) { return(false); } } if (lhs.attributes.POSITION != rhs.attributes.POSITION) { return(false); } if (lhs.attributes.NORMAL != rhs.attributes.NORMAL) { return(false); } if (lhs.attributes.TEXCOORD_0 != rhs.attributes.TEXCOORD_0) { return(false); } if (lhs.attributes.TANGENT != rhs.attributes.TANGENT) { return(false); } if (lhs.attributes.COLOR_0 != rhs.attributes.COLOR_0) { return(false); } if (lhs.attributes.JOINTS_0 != rhs.attributes.JOINTS_0) { return(false); } if (lhs.attributes.WEIGHTS_0 != rhs.attributes.WEIGHTS_0) { return(false); } return(true); }
static Mesh FromGltf(Vrm10Storage storage, glTFMesh x, glTFPrimitives primitive, bool isShared) { var mesh = new Mesh((TopologyType)primitive.mode) { VertexBuffer = primitive.attributes.FromGltf(storage) }; if (isShared) { // create joined index buffer mesh.IndexBuffer = storage.CreateAccessor(x.primitives.Select(y => y.indices).ToArray()); } else { mesh.IndexBuffer = storage.CreateAccessor(primitive.indices); } { gltf_mesh_extras_targetNames.TryGet(x, out List <string> targetNames); for (int i = 0; i < primitive.targets.Count; ++i) { var gltfTarget = primitive.targets[i]; string targetName = null; { targetName = targetNames[i]; } var target = new MorphTarget(targetName) { VertexBuffer = gltfTarget.FromGltf(storage) }; // validate count foreach (var kv in target.VertexBuffer) { if (kv.Value.Count != mesh.VertexBuffer.Count) { throw new Exception(); } } mesh.MorphTargets.Add(target); } } return(mesh); }
public Item(string name, glTFPrimitives primitives) { Name = name; Material = primitives.material; Mode = primitives.mode; if (primitives.attributes != null) { var sb = new List <string>(); if (primitives.attributes.POSITION != -1) { sb.Add($"POS={primitives.attributes.POSITION}"); } if (primitives.attributes.NORMAL != -1) { sb.Add($"NOM={primitives.attributes.NORMAL}"); } if (primitives.attributes.TEXCOORD_0 != -1) { sb.Add($"TEX={primitives.attributes.TEXCOORD_0}"); } if (primitives.attributes.COLOR_0 != -1) { sb.Add($"COL={primitives.attributes.COLOR_0}"); } if (primitives.attributes.JOINTS_0 != -1) { sb.Add($"JOT={primitives.attributes.JOINTS_0}"); } if (primitives.attributes.WEIGHTS_0 != -1) { sb.Add($"WGT={primitives.attributes.WEIGHTS_0}"); } Attributes = string.Join(",", sb); } Indices = primitives.indices; }
/// <summary> /// IndexBuffer毎に異なるVertexBufferを参照する /// /// VertexBuffer /// +--------+ +--------+ +--------+ /// |0 | |1 | |2 | /// +--------+ +--------+ +--------+ /// A A A /// | | | /// +---------+--------+--------+ /// | submesh0|submesh1|submesh2| /// +---------+--------+--------+ /// IndexBuffer /// </summary> public static Mesh FromGltf(this glTFPrimitives primitive, Vrm10Storage storage, glTFMesh x) { return(FromGltf(storage, x, primitive, false)); }
static void ExportMesh(this Mesh mesh, List <object> materials, Vrm10Storage storage, glTFMesh gltfMesh, ExportArgs option) { // // primitive share vertex buffer // var attributeAccessorIndexMap = mesh.VertexBuffer .ToDictionary( kv => kv.Key, kv => kv.Value.AddAccessorTo( storage, 0, option.sparse, kv.Key == VertexBuffer.PositionKey ? (Action <ArraySegment <byte>, glTFAccessor>)Vec3MinMax : null ) ); List <Dictionary <string, int> > morphTargetAccessorIndexMapList = null; if (mesh.MorphTargets.Any()) { morphTargetAccessorIndexMapList = new List <Dictionary <string, int> >(); foreach (var morphTarget in mesh.MorphTargets) { var dict = new Dictionary <string, int>(); foreach (var kv in morphTarget.VertexBuffer) { if (option.removeTangent && kv.Key == VertexBuffer.TangentKey) { // remove tangent continue; } if (option.removeMorphNormal && kv.Key == VertexBuffer.NormalKey) { // normal normal continue; } if (kv.Value.Count != mesh.VertexBuffer.Count) { throw new Exception("inavlid data"); } var accessorIndex = kv.Value.AddAccessorTo(storage, 0, option.sparse, kv.Key == VertexBuffer.PositionKey ? (Action <ArraySegment <byte>, glTFAccessor>)Vec3MinMax : null); dict.Add(kv.Key, accessorIndex); } morphTargetAccessorIndexMapList.Add(dict); } } var drawCountOffset = 0; foreach (var y in mesh.Submeshes) { // index // slide index buffer accessor var indicesAccessorIndex = ExportIndices(storage, mesh.IndexBuffer, drawCountOffset, y.DrawCount, option); drawCountOffset += y.DrawCount; var prim = new glTFPrimitives { mode = (int)mesh.Topology, material = y.Material, indices = indicesAccessorIndex, attributes = new glTFAttributes(), }; gltfMesh.primitives.Add(prim); // attribute foreach (var kv in mesh.VertexBuffer) { var attributeAccessorIndex = attributeAccessorIndexMap[kv.Key]; switch (kv.Key) { case VertexBuffer.PositionKey: prim.attributes.POSITION = attributeAccessorIndex; break; case VertexBuffer.NormalKey: prim.attributes.NORMAL = attributeAccessorIndex; break; case VertexBuffer.ColorKey: prim.attributes.COLOR_0 = attributeAccessorIndex; break; case VertexBuffer.TexCoordKey: prim.attributes.TEXCOORD_0 = attributeAccessorIndex; break; case VertexBuffer.TexCoordKey2: prim.attributes.TEXCOORD_1 = attributeAccessorIndex; break; case VertexBuffer.JointKey: prim.attributes.JOINTS_0 = attributeAccessorIndex; break; case VertexBuffer.WeightKey: prim.attributes.WEIGHTS_0 = attributeAccessorIndex; break; } } // morph target if (mesh.MorphTargets.Any()) { foreach (var(t, accessorIndexMap) in Enumerable.Zip(mesh.MorphTargets, morphTargetAccessorIndexMapList, (t, v) => (t, v))) { var target = new gltfMorphTarget(); prim.targets.Add(target); foreach (var kv in t.VertexBuffer) { if (!accessorIndexMap.TryGetValue(kv.Key, out int targetAccessorIndex)) { continue; } switch (kv.Key) { case VertexBuffer.PositionKey: target.POSITION = targetAccessorIndex; break; case VertexBuffer.NormalKey: target.NORMAL = targetAccessorIndex; break; case VertexBuffer.TangentKey: target.TANGENT = targetAccessorIndex; break; default: throw new NotImplementedException(); } } } } } // target name if (mesh.MorphTargets.Any()) { gltf_mesh_extras_targetNames.Serialize(gltfMesh, mesh.MorphTargets.Select(z => z.Name)); } }
/// <summary> /// IndexBuffer毎に異なるVertexBufferを参照する /// /// VertexBuffer /// +--------+ +--------+ +--------+ /// |0 | |1 | |2 | /// +--------+ +--------+ +--------+ /// A A A /// | | | /// +---------+--------+--------+ /// | submesh0|submesh1|submesh2| /// +---------+--------+--------+ /// IndexBuffer /// </summary> static Mesh FromGltf(this glTFPrimitives primitive, Vrm10ImportData storage, glTFMesh x) { return(FromGltf(storage, x, primitive, false)); }