public static int ExportTexture(glTF gltf, int bufferIndex, Texture texture, glTFTextureTypes textureType) { var bytesWithMime = GetBytesWithMime(texture, textureType);; // add view var view = gltf.buffers[bufferIndex].Append(bytesWithMime.Bytes, glBufferTarget.NONE); var viewIndex = gltf.AddBufferView(view); // add image var imageIndex = gltf.images.Count; gltf.images.Add(new glTFImage { name = texture.name, bufferView = viewIndex, mimeType = bytesWithMime.Mime, }); // add sampler var samplerIndex = gltf.samplers.Count; var sampler = TextureSamplerUtil.Export(texture); gltf.samplers.Add(sampler); // add texture gltf.textures.Add(new glTFTexture { sampler = samplerIndex, source = imageIndex, }); return(imageIndex); }
/// <summary> /// gltf に texture を足す /// /// * textures /// * samplers /// * images /// * bufferViews /// /// を更新し、textures の index を返す /// /// </summary> /// <param name="gltf"></param> /// <param name="bufferIndex"></param> /// <param name="texture"></param> /// <returns>gltf texture index</returns> public static int PushGltfTexture(this glTF gltf, int bufferIndex, Texture2D texture) { var bytesWithMime = GetBytesWithMime(texture); // add view var view = gltf.buffers[bufferIndex].Append(bytesWithMime.bytes, glBufferTarget.NONE); var viewIndex = gltf.AddBufferView(view); // add image var imageIndex = gltf.images.Count; gltf.images.Add(new glTFImage { name = GetTextureParam.RemoveSuffix(texture.name), bufferView = viewIndex, mimeType = bytesWithMime.mine, }); // add sampler var samplerIndex = gltf.samplers.Count; var sampler = TextureSamplerUtil.Export(texture); gltf.samplers.Add(sampler); // add texture var textureIndex = gltf.textures.Count; gltf.textures.Add(new glTFTexture { sampler = samplerIndex, source = imageIndex, }); return(textureIndex); }
public static int ExportTexture(glTF gltf, int bufferIndex, Texture texture) { var bytesWithPath = new BytesWithPath(texture);; // add view var view = gltf.buffers[bufferIndex].Append(bytesWithPath.Bytes, glBufferTarget.NONE); var viewIndex = gltf.AddBufferView(view); // add image var imageIndex = gltf.images.Count; gltf.images.Add(new glTFImage { name = texture.name, bufferView = viewIndex, mimeType = bytesWithPath.Mime, }); // add sampler var filter = default(glFilter); switch (texture.filterMode) { case FilterMode.Point: filter = glFilter.NEAREST; break; default: filter = glFilter.LINEAR; break; } var wrap = default(glWrap); switch (texture.wrapMode) { case TextureWrapMode.Clamp: wrap = glWrap.CLAMP_TO_EDGE; break; case TextureWrapMode.Repeat: wrap = glWrap.REPEAT; break; #if UNITY_2017_OR_NEWER case TextureWrapMode.Mirror: wrap = glWrap.MIRRORED_REPEAT; break; #endif default: throw new NotImplementedException(); } var samplerIndex = gltf.samplers.Count; gltf.samplers.Add(new glTFTextureSampler { magFilter = filter, minFilter = filter, wrapS = wrap, wrapT = wrap, }); // add texture gltf.textures.Add(new glTFTexture { sampler = samplerIndex, source = imageIndex, }); return(imageIndex); }
public static Exported FromGameObject(glTF gltf, GameObject go) { var bytesBuffer = new ArrayByteBuffer(); var bufferIndex = gltf.AddBuffer(bytesBuffer); var unityNodes = go.transform.Traverse() .Skip(1) // exclude root object for the symmetry with the importer .ToList(); #region Material var unityMaterials = unityNodes.SelectMany(x => x.GetSharedMaterials()).Where(x => x != null).Distinct().ToList(); var unityTextures = unityMaterials.SelectMany(x => x.GetTextures()).Where(x => x != null).Distinct().ToList(); for (int i = 0; i < unityTextures.Count; ++i) { var texture = unityTextures[i]; var bytesWithPath = new BytesWithPath(texture);; // add view var view = gltf.buffers[bufferIndex].Storage.Extend(bytesWithPath.Bytes, glBufferTarget.NONE); var viewIndex = gltf.AddBufferView(view); // add image var imageIndex = gltf.images.Count; gltf.images.Add(new glTFImage { bufferView = viewIndex, mimeType = bytesWithPath.Mime, }); // add sampler var filter = default(glFilter); switch (texture.filterMode) { case FilterMode.Point: filter = glFilter.NEAREST; break; default: filter = glFilter.LINEAR; break; } var wrap = default(glWrap); switch (texture.wrapMode) { case TextureWrapMode.Clamp: wrap = glWrap.CLAMP_TO_EDGE; break; case TextureWrapMode.Repeat: wrap = glWrap.REPEAT; break; #if UNITY_2017_OR_NEWER case TextureWrapMode.Mirror: wrap = glWrap.MIRRORED_REPEAT; break; #endif default: throw new NotImplementedException(); } var samplerIndex = gltf.samplers.Count; gltf.samplers.Add(new glTFTextureSampler { magFilter = filter, minFilter = filter, wrapS = wrap, wrapT = wrap, }); // add texture gltf.textures.Add(new glTFTexture { sampler = samplerIndex, source = imageIndex, }); } gltf.materials = unityMaterials.Select(x => ExportMaterial(x, unityTextures)).ToList(); #endregion #region Meshes var unityMeshes = unityNodes .Select(x => new MeshWithRenderer { Mesh = x.GetSharedMesh(), Rendererer = x.GetComponent <Renderer>(), }) .Where(x => x.Mesh != null) .ToList(); for (int i = 0; i < unityMeshes.Count; ++i) { var x = unityMeshes[i]; var mesh = x.Mesh; var materials = x.Rendererer.sharedMaterials; var positions = mesh.vertices.Select(y => y.ReverseZ()).ToArray(); var positionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, positions, glBufferTarget.ARRAY_BUFFER); gltf.accessors[positionAccessorIndex].min = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Min(a.x, b.x), Math.Min(a.y, b.y), Mathf.Min(a.z, b.z))).ToArray(); gltf.accessors[positionAccessorIndex].max = positions.Aggregate(positions[0], (a, b) => new Vector3(Mathf.Max(a.x, b.x), Math.Max(a.y, b.y), Mathf.Max(a.z, b.z))).ToArray(); var normalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.normals.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); var tangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.tangents.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); var colorAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.colors.Select(y => (Vector4)y).ToArray(), glBufferTarget.ARRAY_BUFFER); var uvAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, mesh.uv.Select(y => y.ReverseY()).ToArray(), glBufferTarget.ARRAY_BUFFER); var boneweights = mesh.boneWeights; var weightAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, boneweights.Select(y => new Vector4(y.weight0, y.weight1, y.weight2, y.weight3)).ToArray(), glBufferTarget.ARRAY_BUFFER); var jointsAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, boneweights.Select(y => new UShort4((ushort)y.boneIndex0, (ushort)y.boneIndex1, (ushort)y.boneIndex2, (ushort)y.boneIndex3)).ToArray(), glBufferTarget.ARRAY_BUFFER); var attributes = new glTFAttributes { POSITION = positionAccessorIndex, }; if (normalAccessorIndex != -1) { attributes.NORMAL = normalAccessorIndex; } if (tangentAccessorIndex != -1) { attributes.TANGENT = tangentAccessorIndex; } if (colorAccessorIndex != -1) { attributes.COLOR_0 = colorAccessorIndex; } if (uvAccessorIndex != -1) { attributes.TEXCOORD_0 = uvAccessorIndex; } if (weightAccessorIndex != -1) { attributes.WEIGHTS_0 = weightAccessorIndex; } if (jointsAccessorIndex != -1) { attributes.JOINTS_0 = jointsAccessorIndex; } gltf.meshes.Add(new glTFMesh(mesh.name)); for (int j = 0; j < mesh.subMeshCount; ++j) { var indices = TriangleUtil.FlipTriangle(mesh.GetIndices(j)).Select(y => (uint)y).ToArray(); var indicesAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, indices, glBufferTarget.ELEMENT_ARRAY_BUFFER); gltf.meshes.Last().primitives.Add(new glTFPrimitives { attributes = attributes, indices = indicesAccessorIndex, mode = 4, // triangels ? //material = unityMaterials.IndexOf(materials[j]) material = unityMaterials.IndexOf(materials[0]) // JIA change for Maquette image entity }); } if (mesh.blendShapeCount > 0) { for (int j = 0; j < mesh.blendShapeCount; ++j) { var blendShapeVertices = mesh.vertices; var blendShpaeNormals = mesh.normals; var blendShapeTangents = mesh.tangents.Select(y => (Vector3)y).ToArray(); var blendShapeColors = mesh.colors.Select(y => (Vector4)y).ToArray(); var k = mesh.GetBlendShapeFrameCount(j); mesh.GetBlendShapeFrameVertices(j, k - 1, blendShapeVertices, blendShpaeNormals, null); var blendShapePositionAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, blendShapeVertices.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); var blendShapeNormalAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, blendShpaeNormals.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); var blendShapeTangentAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, blendShapeTangents.Select(y => y.ReverseZ()).ToArray(), glBufferTarget.ARRAY_BUFFER); var blendShapeColorAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, blendShapeColors.ToArray(), glBufferTarget.ARRAY_BUFFER); // // first primitive has whole blendShape // gltf.meshes.Last().primitives[0].targets.Add(new glTFAttributes { POSITION = blendShapePositionAccessorIndex, NORMAL = blendShapeNormalAccessorIndex, TANGENT = blendShapeTangentAccessorIndex, COLOR_0 = blendShapeColorAccessorIndex, }); } } } #endregion #region Skins var unitySkins = unityNodes .Select(x => x.GetComponent <SkinnedMeshRenderer>()).Where(x => x != null) .ToList(); gltf.nodes = unityNodes.Select(x => ExportNode(x, unityNodes, unityMeshes.Select(y => y.Mesh).ToList(), unitySkins)).ToList(); gltf.scenes = new List <gltfScene> { new gltfScene { nodes = go.transform.GetChildren().Select(x => unityNodes.IndexOf(x)).ToArray(), } }; foreach (var x in unitySkins) { var matrices = x.sharedMesh.bindposes.Select(y => y.ReverseZ()).ToArray(); var accessor = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE); var skin = new glTFSkin { inverseBindMatrices = accessor, joints = x.bones.Select(y => unityNodes.IndexOf(y)).ToArray(), skeleton = unityNodes.IndexOf(x.rootBone), }; var skinIndex = gltf.skins.Count; gltf.skins.Add(skin); foreach (var z in unityNodes.Where(y => y.Has(x))) { var nodeIndex = unityNodes.IndexOf(z); gltf.nodes[nodeIndex].skin = skinIndex; } } #endregion #if UNITY_EDITOR #region Animations var animation = go.GetComponent <Animation>(); if (animation != null) { foreach (AnimationState state in animation) { var animationWithCurve = ExportAnimation(state.clip, go.transform, unityNodes); foreach (var kv in animationWithCurve.SamplerMap) { var sampler = animationWithCurve.Animation.samplers[kv.Key]; var inputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Input); sampler.input = inputAccessorIndex; var outputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Output); sampler.output = outputAccessorIndex; // modify accessors var outputAccessor = gltf.accessors[outputAccessorIndex]; var channel = animationWithCurve.Animation.channels.First(x => x.sampler == kv.Key); switch (glTFAnimationTarget.GetElementCount(channel.target.path)) { case 3: outputAccessor.type = "VEC3"; outputAccessor.count /= 3; break; case 4: outputAccessor.type = "VEC4"; outputAccessor.count /= 4; break; default: throw new NotImplementedException(); } } gltf.animations.Add(animationWithCurve.Animation); } } #endregion #endif // glb buffer gltf.buffers[bufferIndex].UpdateByteLength(); return(new Exported { Meshes = unityMeshes, Nodes = unityNodes.Select(x => x.transform).ToList(), Materials = unityMaterials, Textures = unityTextures, }); }