public static void ImportAnimation(ImporterContext ctx) { // animation if (ctx.GLTF.animations != null && ctx.GLTF.animations.Any()) { var animation = ctx.Root.AddComponent <Animation>(); ctx.AnimationClips = ImportAnimationClips(ctx); foreach (var clip in ctx.AnimationClips) { animation.AddClip(clip, clip.name); } if (ctx.AnimationClips.Count > 0) { animation.clip = ctx.AnimationClips.First(); } } }
public static void ImportAsset(string src, string ext, UnityPath prefabPath) { if (!prefabPath.IsUnderAssetsFolder) { Debug.LogWarningFormat("out of asset path: {0}", prefabPath); return; } var context = new ImporterContext(); context.Parse(src); // Extract textures to assets folder context.ExtractImages(prefabPath); ImportDelayed(src, prefabPath, context); }
public static void ImportMenu() { var path = EditorUtility.OpenFilePanel("open gltf", "", "gltf,glb,zip"); if (string.IsNullOrEmpty(path)) { return; } if (Application.isPlaying) { // // load into scene // var context = new ImporterContext(); context.Load(path); context.ShowMeshes(); Selection.activeGameObject = context.Root; } else { // // save as asset // if (path.StartsWithUnityAssetPath()) { Debug.LogWarningFormat("disallow import from folder under the Assets"); return; } var assetPath = EditorUtility.SaveFilePanel("save prefab", "Assets", Path.GetFileNameWithoutExtension(path), "prefab"); if (string.IsNullOrEmpty(path)) { return; } // import as asset gltfAssetPostprocessor.ImportAsset(path, Path.GetExtension(path).ToLower(), UnityPath.FromFullpath(assetPath)); } }
public MeshContext ReadMesh(ImporterContext ctx, int meshIndex) { var gltfMesh = ctx.GLTF.meshes[meshIndex]; bool sharedMorphTarget = gltfMesh.extras != null && gltfMesh.extras.targetNames.Count > 0; MeshContext meshContext; if (sharedMorphTarget) { meshContext = _ImportMeshSharingMorphTarget(ctx, gltfMesh); } else { glTFAttributes lastAttributes = null; var sharedAttributes = true; foreach (var prim in gltfMesh.primitives) { if (lastAttributes != null && !prim.attributes.Equals(lastAttributes)) { sharedAttributes = false; break; } lastAttributes = prim.attributes; } meshContext = sharedAttributes ? _ImportMeshSharingVertexBuffer(ctx, gltfMesh) : _ImportMeshIndependentVertexBuffer(ctx, gltfMesh); } meshContext.name = gltfMesh.name; if (string.IsNullOrEmpty(meshContext.name)) { meshContext.name = string.Format("UniGLTF import#{0}", meshIndex); } return(meshContext); }
// // fix node's coordinate. z-back to z-forward // public static void FixCoordinate(ImporterContext context, List <TransformWithSkin> nodes) { var globalTransformMap = nodes.ToDictionary(x => x.Transform, x => new PosRot { Position = x.Transform.position, Rotation = x.Transform.rotation, }); foreach (var x in context.GLTF.rootnodes) { // fix nodes coordinate // reverse Z in global var t = nodes[x].Transform; //t.SetParent(root.transform, false); foreach (var transform in t.Traverse()) { var g = globalTransformMap[transform]; transform.position = g.Position.ReverseZ(); transform.rotation = g.Rotation.ReverseZ(); } } }
public void UniGLTFSimpleSceneTest() { var go = CreateSimpleScene(); var context = new ImporterContext(); try { // export var gltf = new glTF(); string json = null; using (var exporter = new gltfExporter(gltf)) { exporter.Prepare(go); exporter.Export(); // remove empty buffer gltf.buffers.Clear(); json = gltf.ToJson(); } // import context.ParseJson(json, new SimpleStorage(new ArraySegment <byte>())); //Debug.LogFormat("{0}", context.Json); context.Load(); AssertAreEqual(go.transform, context.Root.transform); } finally { //Debug.LogFormat("Destroy, {0}", go.name); GameObject.DestroyImmediate(go); context.EditorDestroyRootAndAssets(); } }
public static List <AnimationClip> ImportAnimationClip(ImporterContext ctx) { List <AnimationClip> animasionClips = new List <AnimationClip>(); for (int i = 0; i < ctx.GLTF.animations.Count; ++i) { var clip = new AnimationClip(); clip.ClearCurves(); clip.legacy = true; clip.name = ctx.GLTF.animations[i].name; if (string.IsNullOrEmpty(clip.name)) { clip.name = "legacy_" + i; } clip.wrapMode = WrapMode.Loop; var animation = ctx.GLTF.animations[i]; if (string.IsNullOrEmpty(animation.name)) { animation.name = string.Format("animation:{0}", i); } foreach (var channel in animation.channels) { var targetTransform = ctx.Nodes[channel.target.node]; var relativePath = targetTransform.RelativePathFrom(ctx.Root.transform); switch (channel.target.path) { case glTFAnimationTarget.PATH_TRANSLATION: { var sampler = animation.samplers[channel.sampler]; var input = ctx.GLTF.GetArrayFromAccessor <float>(sampler.input); var output = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output); AnimationImporter.SetAnimationCurve( clip, relativePath, new string[] { "localPosition.x", "localPosition.y", "localPosition.z" }, input, output, sampler.interpolation, typeof(Transform), (values, last) => { Vector3 temp = new Vector3(values[0], values[1], values[2]); return(temp.ReverseZ().ToArray()); } ); } break; case glTFAnimationTarget.PATH_ROTATION: { var sampler = animation.samplers[channel.sampler]; var input = ctx.GLTF.GetArrayFromAccessor <float>(sampler.input); var output = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output); AnimationImporter.SetAnimationCurve( clip, relativePath, new string[] { "localRotation.x", "localRotation.y", "localRotation.z", "localRotation.w" }, input, output, sampler.interpolation, typeof(Transform), (values, last) => { Quaternion currentQuaternion = new Quaternion(values[0], values[1], values[2], values[3]); Quaternion lastQuaternion = new Quaternion(last[0], last[1], last[2], last[3]); return(AnimationImporter.GetShortest(lastQuaternion, currentQuaternion.ReverseZ()).ToArray()); } ); clip.EnsureQuaternionContinuity(); } break; case glTFAnimationTarget.PATH_SCALE: { var sampler = animation.samplers[channel.sampler]; var input = ctx.GLTF.GetArrayFromAccessor <float>(sampler.input); var output = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output); AnimationImporter.SetAnimationCurve( clip, relativePath, new string[] { "localScale.x", "localScale.y", "localScale.z" }, input, output, sampler.interpolation, typeof(Transform), (values, last) => values); } break; case glTFAnimationTarget.PATH_WEIGHT: { var node = ctx.GLTF.nodes[channel.target.node]; var mesh = ctx.GLTF.meshes[node.mesh]; //var primitive = mesh.primitives.FirstOrDefault(); //var targets = primitive.targets; List <string> blendShapeNames = new List <string>(); var transform = ctx.Nodes[channel.target.node]; var skinnedMeshRenderer = transform.GetComponent <SkinnedMeshRenderer>(); if (skinnedMeshRenderer == null) { continue; } for (int j = 0; j < skinnedMeshRenderer.sharedMesh.blendShapeCount; j++) { blendShapeNames.Add(skinnedMeshRenderer.sharedMesh.GetBlendShapeName(j)); } var keyNames = blendShapeNames .Where(x => !string.IsNullOrEmpty(x)) .Select(x => "blendShape." + x) .ToArray(); var sampler = animation.samplers[channel.sampler]; var input = ctx.GLTF.GetArrayFromAccessor <float>(sampler.input); var output = ctx.GLTF.GetArrayFromAccessor <float>(sampler.output); AnimationImporter.SetAnimationCurve( clip, relativePath, keyNames, input, output, sampler.interpolation, typeof(SkinnedMeshRenderer), (values, last) => { for (int j = 0; j < values.Length; j++) { values[j] *= 100.0f; } return(values); }); } break; default: Debug.LogWarningFormat("unknown path: {0}", channel.target.path); break; } } animasionClips.Add(clip); } return(animasionClips); }
//ImporterContext m_context; public ShaderStore(ImporterContext _) { //m_context = context; }
public static MeshWithMaterials BuildMesh(ImporterContext ctx, MeshImporter.MeshContext meshContext) { if (!meshContext.materialIndices.Any()) { meshContext.materialIndices.Add(0); } //Debug.Log(prims.ToJson()); var mesh = new Mesh(); mesh.name = meshContext.name; if (meshContext.positions.Length > UInt16.MaxValue) { #if UNITY_2017_3_OR_NEWER mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; #else Debug.LogWarningFormat("vertices {0} exceed 65535. not implemented. Unity2017.3 supports large mesh", meshContext.positions.Length); #endif } mesh.vertices = meshContext.positions; bool recalculateNormals = false; if (meshContext.normals != null && meshContext.normals.Length > 0) { mesh.normals = meshContext.normals; } else { recalculateNormals = true; } if (meshContext.uv != null && meshContext.uv.Length > 0) { mesh.uv = meshContext.uv; } bool recalculateTangents = true; #if UNIGLTF_IMPORT_TANGENTS if (meshContext.tangents != null && meshContext.tangents.Length > 0) { mesh.tangents = meshContext.tangents; recalculateTangents = false; } #endif if (meshContext.colors != null && meshContext.colors.Length > 0) { mesh.colors = meshContext.colors; } if (meshContext.boneWeights != null && meshContext.boneWeights.Count > 0) { mesh.boneWeights = meshContext.boneWeights.ToArray(); } mesh.subMeshCount = meshContext.subMeshes.Count; for (int i = 0; i < meshContext.subMeshes.Count; ++i) { mesh.SetTriangles(meshContext.subMeshes[i], i); } if (recalculateNormals) { mesh.RecalculateNormals(); } if (recalculateTangents) { #if UNITY_5_6_OR_NEWER mesh.RecalculateTangents(); #else CalcTangents(mesh); #endif } var result = new MeshWithMaterials { Mesh = mesh, Materials = meshContext.materialIndices.Select(x => ctx.GetMaterial(x)).ToArray() }; if (meshContext.blendShapes != null) { Vector3[] emptyVertices = null; foreach (var blendShape in meshContext.blendShapes) { if (blendShape.Positions.Count > 0) { if (blendShape.Positions.Count == mesh.vertexCount) { mesh.AddBlendShapeFrame(blendShape.Name, FRAME_WEIGHT, blendShape.Positions.ToArray(), (meshContext.normals != null && meshContext.normals.Length == mesh.vertexCount && blendShape.Normals.Count() == blendShape.Positions.Count()) ? blendShape.Normals.ToArray() : null, null ); } else { Debug.LogWarningFormat("May be partial primitive has blendShape. Require separate mesh or extend blend shape, but not implemented: {0}", blendShape.Name); } } else { if (emptyVertices == null) { emptyVertices = new Vector3[mesh.vertexCount]; } // Debug.LogFormat("empty blendshape: {0}.{1}", mesh.name, blendShape.Name); // add empty blend shape for keep blend shape index mesh.AddBlendShapeFrame(blendShape.Name, FRAME_WEIGHT, emptyVertices, null, null ); } } } return(result); }
// multiple submMesh is not sharing a VertexBuffer. // each subMesh use a independent VertexBuffer. private static MeshContext _ImportMeshIndependentVertexBuffer(ImporterContext ctx, glTFMesh gltfMesh) { //Debug.LogWarning("_ImportMeshIndependentVertexBuffer"); var targets = gltfMesh.primitives[0].targets; for (int i = 1; i < gltfMesh.primitives.Count; ++i) { if (!gltfMesh.primitives[i].targets.SequenceEqual(targets)) { throw new NotImplementedException(string.Format("different targets: {0} with {1}", gltfMesh.primitives[i], targets)); } } var positions = new List <Vector3>(); var normals = new List <Vector3>(); var tangents = new List <Vector4>(); var uv = new List <Vector2>(); var colors = new List <Color>(); var meshContext = new MeshContext(); foreach (var prim in gltfMesh.primitives) { var indexOffset = positions.Count; var indexBuffer = prim.indices; var positionCount = positions.Count; positions.AddRange(ctx.GLTF.GetArrayFromAccessor <Vector3>(prim.attributes.POSITION).Select(x => x.ReverseZ())); positionCount = positions.Count - positionCount; // normal if (prim.attributes.NORMAL != -1) { normals.AddRange(ctx.GLTF.GetArrayFromAccessor <Vector3>(prim.attributes.NORMAL).Select(x => x.ReverseZ())); } if (prim.attributes.TANGENT != -1) { tangents.AddRange(ctx.GLTF.GetArrayFromAccessor <Vector4>(prim.attributes.TANGENT).Select(x => x.ReverseZ())); } // uv if (prim.attributes.TEXCOORD_0 != -1) { if (ctx.IsGeneratedUniGLTFAndOlder(1, 16)) { #pragma warning disable 0612 // backward compatibility uv.AddRange(ctx.GLTF.GetArrayFromAccessor <Vector2>(prim.attributes.TEXCOORD_0).Select(x => x.ReverseY())); #pragma warning restore 0612 } else { uv.AddRange(ctx.GLTF.GetArrayFromAccessor <Vector2>(prim.attributes.TEXCOORD_0).Select(x => x.ReverseUV())); } } else { // for inconsistent attributes in primitives uv.AddRange(new Vector2[positionCount]); } // color if (prim.attributes.COLOR_0 != -1) { colors.AddRange(ctx.GLTF.GetArrayFromAccessor <Color>(prim.attributes.COLOR_0)); } // skin if (prim.attributes.JOINTS_0 != -1 && prim.attributes.WEIGHTS_0 != -1) { var joints0 = ctx.GLTF.GetArrayFromAccessor <UShort4>(prim.attributes.JOINTS_0); // uint4 var weights0 = ctx.GLTF.GetArrayFromAccessor <Float4>(prim.attributes.WEIGHTS_0).Select(x => x.One()).ToArray(); for (int j = 0; j < joints0.Length; ++j) { var bw = new BoneWeight(); bw.boneIndex0 = joints0[j].x; bw.weight0 = weights0[j].x; bw.boneIndex1 = joints0[j].y; bw.weight1 = weights0[j].y; bw.boneIndex2 = joints0[j].z; bw.weight2 = weights0[j].z; bw.boneIndex3 = joints0[j].w; bw.weight3 = weights0[j].w; meshContext.boneWeights.Add(bw); } } // blendshape if (prim.targets != null && prim.targets.Count > 0) { for (int i = 0; i < prim.targets.Count; ++i) { //var name = string.Format("target{0}", i++); var primTarget = prim.targets[i]; var blendShape = new BlendShape(!string.IsNullOrEmpty(prim.extras.targetNames[i]) ? prim.extras.targetNames[i] : i.ToString()) ; if (primTarget.POSITION != -1) { blendShape.Positions.AddRange( ctx.GLTF.GetArrayFromAccessor <Vector3>(primTarget.POSITION).Select(x => x.ReverseZ()).ToArray()); } if (primTarget.NORMAL != -1) { blendShape.Normals.AddRange( ctx.GLTF.GetArrayFromAccessor <Vector3>(primTarget.NORMAL).Select(x => x.ReverseZ()).ToArray()); } if (primTarget.TANGENT != -1) { blendShape.Tangents.AddRange( ctx.GLTF.GetArrayFromAccessor <Vector3>(primTarget.TANGENT).Select(x => x.ReverseZ()).ToArray()); } meshContext.blendShapes.Add(blendShape); } } var indices = (indexBuffer >= 0) ? ctx.GLTF.GetIndices(indexBuffer) : TriangleUtil.FlipTriangle(Enumerable.Range(0, meshContext.positions.Length)).ToArray() // without index array ; for (int i = 0; i < indices.Length; ++i) { indices[i] += indexOffset; } meshContext.subMeshes.Add(indices); // material meshContext.materialIndices.Add(prim.material); } meshContext.positions = positions.ToArray(); meshContext.normals = normals.ToArray(); meshContext.tangents = tangents.ToArray(); meshContext.uv = uv.ToArray(); return(meshContext); }
public static void Load(ImporterContext context) { context.Load(); context.ShowMeshes(); context.EnableUpdateWhenOffscreen(); }
public void Import(ImporterContext context) { var animationClips = new AnimationClip[context.GLTF.animations.Count]; // node extension animation for (int i = 0; i < context.GLTF.nodes.Count; i++) { var node = context.GLTF.nodes[i]; if (node.extensions == null || node.extensions.VCAST_vci_animation == null) { continue; } var vciAnimation = node.extensions.VCAST_vci_animation; var root = context.Nodes[i]; var animation = root.gameObject.AddComponent <Animation>(); foreach (var animationReference in vciAnimation.animationReferences) { var gltfAnimation = context.GLTF.animations[animationReference.animation]; AnimationClip clip = null; if (animationClips[animationReference.animation] == null) { clip = AnimationImporterUtil.ImportAnimationClip(context, gltfAnimation, root); animationClips[animationReference.animation] = clip; } else { clip = animationClips[animationReference.animation]; } if (clip != null) { animation.AddClip(clip, clip.name); } } } // root animation var rootAnimation = context.Root.GetComponent <Animation>(); if (rootAnimation == null) { rootAnimation = context.Root.AddComponent <Animation>(); } for (int i = 0; i < animationClips.Length; i++) { if (animationClips[i] != null) { continue; } var gltfAnimation = context.GLTF.animations[i]; animationClips[i] = AnimationImporterUtil.ImportAnimationClip(context, gltfAnimation, context.Root.transform); rootAnimation.AddClip(animationClips[i], animationClips[i].name); } context.AnimationClips = new List <AnimationClip>(animationClips); }
public void SameMeshButDifferentMaterialExport() { var go = new GameObject("same_mesh"); try { var shader = Shader.Find("Unlit/Color"); var cubeA = GameObject.CreatePrimitive(PrimitiveType.Cube); { cubeA.transform.SetParent(go.transform); var material = new Material(shader); material.name = "red"; material.color = Color.red; cubeA.GetComponent <Renderer>().sharedMaterial = material; } { var cubeB = GameObject.Instantiate(cubeA); cubeB.transform.SetParent(go.transform); var material = new Material(shader); material.color = Color.blue; material.name = "blue"; cubeB.GetComponent <Renderer>().sharedMaterial = material; Assert.AreEqual(cubeB.GetComponent <MeshFilter>().sharedMesh, cubeA.GetComponent <MeshFilter>().sharedMesh); } // export var gltf = new glTF(); var json = default(string); using (var exporter = new gltfExporter(gltf)) { exporter.Prepare(go); exporter.Export(); json = gltf.ToJson(); } Assert.AreEqual(2, gltf.meshes.Count); var red = gltf.materials[gltf.meshes[0].primitives[0].material]; Assert.AreEqual(new float[] { 1, 0, 0, 1 }, red.pbrMetallicRoughness.baseColorFactor); var blue = gltf.materials[gltf.meshes[1].primitives[0].material]; Assert.AreEqual(new float[] { 0, 0, 1, 1 }, blue.pbrMetallicRoughness.baseColorFactor); Assert.AreEqual(2, gltf.nodes.Count); Assert.AreNotEqual(gltf.nodes[0].mesh, gltf.nodes[1].mesh); // import { var context = new ImporterContext(); context.ParseJson(json, new SimpleStorage(new ArraySegment <byte>(new byte[1024 * 1024]))); //Debug.LogFormat("{0}", context.Json); context.Load(); var importedRed = context.Root.transform.GetChild(0); var importedRedMaterial = importedRed.GetComponent <Renderer>().sharedMaterial; Assert.AreEqual("red", importedRedMaterial.name); Assert.AreEqual(Color.red, importedRedMaterial.color); var importedBlue = context.Root.transform.GetChild(1); var importedBlueMaterial = importedBlue.GetComponent <Renderer>().sharedMaterial; Assert.AreEqual("blue", importedBlueMaterial.name); Assert.AreEqual(Color.blue, importedBlueMaterial.color); } // import new version { var context = new ImporterContext { SerializerType = SerializerTypes.UniJSON }; context.ParseJson(json, new SimpleStorage(new ArraySegment <byte>(new byte[1024 * 1024]))); //Debug.LogFormat("{0}", context.Json); context.Load(); var importedRed = context.Root.transform.GetChild(0); var importedRedMaterial = importedRed.GetComponent <Renderer>().sharedMaterial; Assert.AreEqual("red", importedRedMaterial.name); Assert.AreEqual(Color.red, importedRedMaterial.color); var importedBlue = context.Root.transform.GetChild(1); var importedBlueMaterial = importedBlue.GetComponent <Renderer>().sharedMaterial; Assert.AreEqual("blue", importedBlueMaterial.name); Assert.AreEqual(Color.blue, importedBlueMaterial.color); } } finally { GameObject.DestroyImmediate(go); } }
public static void SetupSkinning(ImporterContext context, List <TransformWithSkin> nodes, int i) { var x = nodes[i]; var skinnedMeshRenderer = x.Transform.GetComponent <SkinnedMeshRenderer>(); if (skinnedMeshRenderer != null) { var mesh = skinnedMeshRenderer.sharedMesh; if (x.SkinIndex.HasValue) { if (mesh == null) { throw new Exception(); } if (skinnedMeshRenderer == null) { throw new Exception(); } if (x.SkinIndex.Value < context.GLTF.skins.Count) { // calculate internal values(boundingBox etc...) when sharedMesh assigned ? skinnedMeshRenderer.sharedMesh = null; var skin = context.GLTF.skins[x.SkinIndex.Value]; var joints = skin.joints.Select(y => nodes[y].Transform).ToArray(); if (joints.Any()) { // have bones skinnedMeshRenderer.bones = joints; if (skin.inverseBindMatrices != -1) { var bindPoses = context.GLTF.GetArrayFromAccessor <Matrix4x4>(skin.inverseBindMatrices) .Select(y => y.ReverseZ()) .ToArray() ; mesh.bindposes = bindPoses; } else { // // calc default matrices // https://docs.unity3d.com/ScriptReference/Mesh-bindposes.html // var meshCoords = skinnedMeshRenderer.transform; // ? var calculatedBindPoses = joints.Select(y => y.worldToLocalMatrix * meshCoords.localToWorldMatrix).ToArray(); mesh.bindposes = calculatedBindPoses; } } else { // BlendShape only ? } skinnedMeshRenderer.sharedMesh = mesh; if (skin.skeleton >= 0 && skin.skeleton < nodes.Count) { skinnedMeshRenderer.rootBone = nodes[skin.skeleton].Transform; } } } } }
// multiple submesh sharing same VertexBuffer private static MeshContext _ImportMeshSharingVertexBuffer(ImporterContext ctx, glTFMesh gltfMesh) { var context = new MeshContext(); { var prim = gltfMesh.primitives.First(); context.positions = ctx.GLTF.GetArrayFromAccessor <Vector3>(prim.attributes.POSITION).SelectInplace(x => x.ReverseZ()); // normal if (prim.attributes.NORMAL != -1) { context.normals = ctx.GLTF.GetArrayFromAccessor <Vector3>(prim.attributes.NORMAL).SelectInplace(x => x.ReverseZ()); } // tangent if (prim.attributes.TANGENT != -1) { context.tangents = ctx.GLTF.GetArrayFromAccessor <Vector4>(prim.attributes.TANGENT).SelectInplace(x => x.ReverseZ()); } // uv if (prim.attributes.TEXCOORD_0 != -1) { if (ctx.IsGeneratedUniGLTFAndOlder(1, 16)) { #pragma warning disable 0612 // backward compatibility context.uv = ctx.GLTF.GetArrayFromAccessor <Vector2>(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseY()); #pragma warning restore 0612 } else { context.uv = ctx.GLTF.GetArrayFromAccessor <Vector2>(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseUV()); } } else { // for inconsistent attributes in primitives context.uv = new Vector2[context.positions.Length]; } // color if (prim.attributes.COLOR_0 != -1) { if (ctx.GLTF.accessors[prim.attributes.COLOR_0].TypeCount == 3) { var vec3Color = ctx.GLTF.GetArrayFromAccessor <Vector3>(prim.attributes.COLOR_0); context.colors = new Color[vec3Color.Length]; for (int i = 0; i < vec3Color.Length; i++) { Vector3 color = vec3Color[i]; context.colors[i] = new Color(color.x, color.y, color.z); } } else if (ctx.GLTF.accessors[prim.attributes.COLOR_0].TypeCount == 4) { context.colors = ctx.GLTF.GetArrayFromAccessor <Color>(prim.attributes.COLOR_0); } else { throw new NotImplementedException(string.Format("unknown color type {0}", ctx.GLTF.accessors[prim.attributes.COLOR_0].type)); } } // skin if (prim.attributes.JOINTS_0 != -1 && prim.attributes.WEIGHTS_0 != -1) { var joints0 = ctx.GLTF.GetArrayFromAccessor <UShort4>(prim.attributes.JOINTS_0); // uint4 var weights0 = ctx.GLTF.GetArrayFromAccessor <Float4>(prim.attributes.WEIGHTS_0); for (int i = 0; i < weights0.Length; ++i) { weights0[i] = weights0[i].One(); } for (int j = 0; j < joints0.Length; ++j) { var bw = new BoneWeight(); bw.boneIndex0 = joints0[j].x; bw.weight0 = weights0[j].x; bw.boneIndex1 = joints0[j].y; bw.weight1 = weights0[j].y; bw.boneIndex2 = joints0[j].z; bw.weight2 = weights0[j].z; bw.boneIndex3 = joints0[j].w; bw.weight3 = weights0[j].w; context.boneWeights.Add(bw); } } // blendshape if (prim.targets != null && prim.targets.Count > 0) { context.blendShapes.AddRange(prim.targets.Select((x, i) => new BlendShape( i < prim.extras.targetNames.Count && !string.IsNullOrEmpty(prim.extras.targetNames[i]) ? prim.extras.targetNames[i] : i.ToString()))); for (int i = 0; i < prim.targets.Count; ++i) { //var name = string.Format("target{0}", i++); var primTarget = prim.targets[i]; var blendShape = context.blendShapes[i]; if (primTarget.POSITION != -1) { blendShape.Positions.Assign( ctx.GLTF.GetArrayFromAccessor <Vector3>(primTarget.POSITION), x => x.ReverseZ()); } if (primTarget.NORMAL != -1) { blendShape.Normals.Assign( ctx.GLTF.GetArrayFromAccessor <Vector3>(primTarget.NORMAL), x => x.ReverseZ()); } if (primTarget.TANGENT != -1) { blendShape.Tangents.Assign( ctx.GLTF.GetArrayFromAccessor <Vector3>(primTarget.TANGENT), x => x.ReverseZ()); } } } } foreach (var prim in gltfMesh.primitives) { if (prim.indices == -1) { context.subMeshes.Add(TriangleUtil.FlipTriangle(Enumerable.Range(0, context.positions.Length)).ToArray()); } else { var indices = ctx.GLTF.GetIndices(prim.indices); context.subMeshes.Add(indices); } // material context.materialIndices.Add(prim.material); } return(context); }
public static TransformWithSkin BuildHierarchy(ImporterContext context, int i) { var go = context.Nodes[i].gameObject; if (string.IsNullOrEmpty(go.name)) { go.name = string.Format("node{0:000}", i); } var nodeWithSkin = new TransformWithSkin { Transform = go.transform, }; // // build hierarchy // var node = context.GLTF.nodes[i]; if (node.children != null) { foreach (var child in node.children) { context.Nodes[child].transform.SetParent(context.Nodes[i].transform, false // node has local transform ); } } // // attach mesh // if (node.mesh != -1) { var mesh = context.Meshes[node.mesh]; if (mesh.Mesh.blendShapeCount == 0 && node.skin == -1) { // without blendshape and bone skinning var filter = go.AddComponent <MeshFilter>(); filter.sharedMesh = mesh.Mesh; var renderer = go.AddComponent <MeshRenderer>(); renderer.sharedMaterials = mesh.Materials; // invisible in loading renderer.enabled = false; mesh.Renderers.Add(renderer); } else { var renderer = go.AddComponent <SkinnedMeshRenderer>(); if (node.skin != -1) { nodeWithSkin.SkinIndex = node.skin; } renderer.sharedMesh = mesh.Mesh; renderer.sharedMaterials = mesh.Materials; // invisible in loading renderer.enabled = false; mesh.Renderers.Add(renderer); } } return(nodeWithSkin); }
public MaterialImporter(IShaderStore shaderStore, ImporterContext context) { m_shaderStore = shaderStore; m_context = context; }