예제 #1
0
            public void BuildModel(int modelIndex)
            {
                _srModel = _srFile.Models[modelIndex];
                String modelName = _objectName + "-" + modelIndex.ToString();

                #region Materials
                ProgressStage = "Model " + modelIndex.ToString() + " - Creating Materials";
                Thread.Sleep(500);
                for (int materialIndex = 0; materialIndex < _srModel.MaterialCount; materialIndex++)
                {
                    Material material     = new Material();
                    Color    colorDiffuse = Color.FromArgb((int)unchecked (_srModel.Materials[materialIndex].colour));
                    material.Diffuse         = colorDiffuse;
                    material.TextureFileName = GetTextureName(_srModel, materialIndex);
                    Materials.Add(material);

                    progressLevel += _srModel.IndexCount / _srModel.Groups.Length;
                }
                #endregion

                #region Groups
                for (int groupIndex = 0; groupIndex < _srModel.Groups.Length; groupIndex++)
                {
                    ProgressStage = "Model " + modelIndex.ToString() + " - Creating Group " + groupIndex.ToString();
                    Thread.Sleep(100);

                    Tree   srGroup   = _srModel.Groups[groupIndex];
                    String groupName = String.Format("{0}-{1}-group-{2}", _objectName, modelIndex, groupIndex);
                    if (srGroup != null && srGroup.mesh != null &&
                        srGroup.mesh.indexCount > 0 && srGroup.mesh.polygonCount > 0)
                    {
                        Node         group      = new Node();
                        SRMeshParser meshParser = new SRMeshParser(_objectName, _srFile);
                        meshParser.BuildMesh(modelIndex, groupIndex, 0);
                        foreach (SubMesh subMesh in meshParser.SubMeshes)
                        {
                            // If the mesh parser knew the total submeshes for the model,
                            // then this could be done inside BuildMesh.
                            subMesh.MeshIndex = Meshes.Count;
                            group.SubMeshIndices.Add(SubMeshes.Count);
                            SubMeshes.Add(subMesh);
                        }
                        Meshes.Add(meshParser.Mesh);
                        group.Name = groupName;
                        Groups.Add(group);
                    }
                }
                #endregion

                ModelName = modelName;

                if (_srFile.Asset == CDC.Asset.Unit)
                {
                    Model = new Unit(this);
                }
                else
                {
                    Model = new Physical(this);
                }
            }
예제 #2
0
파일: Model.cs 프로젝트: afradley/ModelEx5
 public Model(IModelParser modelParser)
 {
     Name = modelParser.ModelName;
     Materials.AddRange(modelParser.Materials);
     Meshes.AddRange(modelParser.Meshes);
     SubMeshes.AddRange(modelParser.SubMeshes);
     Root.Nodes.AddRange(modelParser.Groups);
     Root.Name = modelParser.ModelName;
 }
예제 #3
0
        public void BuildModel(RenderResource resource, int modelIndex, CDC.Objects.ExportOptions options)
        {
            _srModel = _srFile.Models[modelIndex];
            String modelName = _objectName + "-" + modelIndex.ToString();

            #region Materials

            for (int materialIndex = 0; materialIndex < _srModel.MaterialCount; materialIndex++)
            {
                Material material = new Material();
                material.Visible = _srModel.Materials[materialIndex].visible;
                // Breaks early SR1 builds.
                //material.BlendMode = _srModel.Materials[materialIndex].blendMode;
                //int sortPush = unchecked((sbyte)_srModel.Materials[materialIndex].sortPush);
                //sortPush = 128 - sortPush;
                //material.DepthBias = (1.0f / 100000.0f) * sortPush;
                // Maybe use a hack for warpgates WARPGATE_DrawWarpGateRim indicates tree 3 should have lower priority.
                Color colorDiffuse = Color.FromArgb((int)unchecked (_srModel.Materials[materialIndex].colour));
                material.Diffuse         = colorDiffuse;
                material.TextureFileName = CDC.Objects.Models.SRModel.GetTextureName(_srModel, materialIndex, options);
                Materials.Add(material);
            }

            #endregion

            #region Groups
            for (int groupIndex = 0; groupIndex < _srModel.Groups.Length; groupIndex++)
            {
                Tree   srGroup   = _srModel.Groups[groupIndex];
                String groupName = String.Format("{0}-{1}-group-{2}", _objectName, modelIndex, groupIndex);
                if (srGroup != null && srGroup.mesh != null &&
                    srGroup.mesh.indexCount > 0 && srGroup.mesh.polygonCount > 0)
                {
                    ModelNode    group      = new ModelNode();
                    SRMeshParser meshParser = new SRMeshParser(_objectName, _srFile);
                    meshParser.BuildMesh(resource, modelIndex, groupIndex, 0);
                    foreach (SubMesh subMesh in meshParser.SubMeshes)
                    {
                        // If the mesh parser knew the total submeshes for the model,
                        // then this could be done inside BuildMesh.
                        subMesh.MeshIndex = Meshes.Count;
                        group.SubMeshIndices.Add(SubMeshes.Count);
                        SubMeshes.Add(subMesh);
                    }
                    Meshes.Add(meshParser.Mesh);
                    group.Name = groupName;
                    Groups.Add(group);
                }
            }
            #endregion

            ModelName = modelName;
            Model     = new Model(this);
        }
예제 #4
0
        public void MergeSubMeshes()
        {
            var submesh = new ObjSubMesh(this);

            submesh.PositionFaces = SubMeshes.SelectMany(i => i.PositionFaces).ToList();
            submesh.NormalFaces   = SubMeshes.SelectMany(i => i.NormalFaces).ToList();
            submesh.TexCoordFaces = SubMeshes.SelectMany(i => i.TexCoordFaces).ToList();

            SubMeshes.Clear();
            SubMeshes.Add(submesh);
        }
예제 #5
0
        internal void Read(EndianBinaryReader reader, MeshSection section = null)
        {
            uint signature = reader.ReadUInt32();

            reader.SeekCurrent(4);

            int  subMeshCount, materialCount;
            long subMeshesOffset, materialsOffset;

            // X stores submesh/material count before the bounding sphere
            if (section?.Format == BinaryFormat.X)
            {
                subMeshCount    = reader.ReadInt32();
                materialCount   = reader.ReadInt32();
                BoundingSphere  = reader.ReadBoundingSphere();
                subMeshesOffset = reader.ReadOffset();
                materialsOffset = reader.ReadOffset();
            }

            else
            {
                BoundingSphere  = reader.ReadBoundingSphere();
                subMeshCount    = reader.ReadInt32();
                subMeshesOffset = reader.ReadOffset();
                materialCount   = reader.ReadInt32();
                materialsOffset = reader.ReadOffset();
            }

            SubMeshes.Capacity = subMeshCount;
            for (int i = 0; i < subMeshCount; i++)
            {
                reader.ReadAtOffset(subMeshesOffset + i * SubMesh.GetByteSize(section?.Format ?? BinaryFormat.DT), () =>
                {
                    var submesh = new SubMesh();
                    submesh.Read(reader, section);
                    SubMeshes.Add(submesh);
                });
            }

            Materials.Capacity = materialCount;
            for (int i = 0; i < materialCount; i++)
            {
                reader.ReadAtOffset(materialsOffset + i * Material.BYTE_SIZE, () =>
                {
                    var material = new Material();
                    material.Read(reader);
                    Materials.Add(material);
                });
            }
        }
예제 #6
0
 private void Start()
 {
     childMeshRenderers = new List <SubMeshes>();
     Diago.GetComponentInChildren <Renderer>().enabled = false;
     // testBtn = testBtn.GetComponent<Button>();
     // testBtn.onClick.AddListener(sendOutput);
     //
     foreach (var item in GetComponentsInChildren <MeshRenderer>())
     {
         SubMeshes mesh = new SubMeshes();
         mesh.meshRenderer     = item;
         mesh.originalPosition = item.transform.position;
         mesh.explodedPosition = item.bounds.center * 1.7f;
         childMeshRenderers.Add(mesh);
     }
 }
예제 #7
0
 /// <summary>
 /// Checks whether the ray intersects the mesh or not
 /// </summary>
 /// <param name="src"></param>
 /// <param name="dir"></param>
 /// <returns></returns>
 public bool Intersect(Vector3 src, Vector3 dir)
 {
     if (SubMeshes.Length > 0)
     {
         // 1. Ray
         if (SubMeshes.Any(m => m.Intersect(src, dir)))
         {
             return(true);
         }
     }
     if (Mesh != null && Mesh.Intersect(src, dir))
     {
         return(true);
     }
     return(false);
 }
예제 #8
0
        public ushort CreateFreshSubMesh(ushort vertsToReserve, ushort trisToReserve)
        {
            // create custom List<> implementation with NativeArray that supports growth without assignment!
            SubMesh subMesh = new SubMesh((ushort)Verts.Count, (ushort)Tris.Count, vertsToReserve, trisToReserve);

            lastVert += vertsToReserve;
            lastTri  += trisToReserve;
            SubMeshes.Add(subMesh);
            for (int i = 0; i < vertsToReserve; i++)
            {
                Verts.Add(Vector3.zero); // this is multiple assignment! BAD!
                Normals.Add(Vector3.up);
                TextureUVs.Add(Vector2.zero);
                SubmaterialUVs.Add(Vector2.zero);
            }
            for (int i = 0; i < trisToReserve; i++)
            {
                Tris.Add(0); // more evil multiple assignment!
            }
            return((ushort)(SubMeshes.Count + SubMeshBaseIdx - 1));
        }
예제 #9
0
파일: Mesh.cs 프로젝트: bmjoy/UnityRipper
        protected override YAMLMappingNode ExportYAMLRoot()
        {
#warning TODO: provide for null values

            YAMLMappingNode node = base.ExportYAMLRoot();
            node.AddSerializedVersion(SerializedVersion);
            node.Add("m_SubMeshes", SubMeshes.ExportYAML());
            node.Add("m_Shapes", Shapes.ExportYAML());
            node.Add("m_BindPose", BindPoses.ExportYAML());
#warning ???
            node.Add("m_BoneNames", YAMLSequenceNode.Empty);
            node.Add("m_BoneNameHashes", BoneNameHashes.ExportYAML(false));
#warning ???
            node.Add("m_RootBoneName", YAMLScalarNode.Empty);
            node.Add("m_RootBoneNameHash", RootBoneNameHash);
            node.Add("m_MeshCompression", MeshCompression);
            node.Add("m_IsReadable", IsReadable);
            node.Add("m_KeepVertices", KeepVertices);
            node.Add("m_KeepIndices", KeepIndices);
            node.Add("m_IndexBuffer", IndexBuffer.ExportYAML());
            node.Add("m_Skin", Skin.ExportYAML());
            node.Add("m_VertexData", VertexData.ExportYAML());
            node.Add("m_CompressedMesh", CompressedMesh.ExportYAML());
            node.Add("m_LocalAABB", LocalAABB.ExportYAML());
            node.Add("m_MeshUsageFlags", MeshUsageFlags);
            if (IsReadCollision)
            {
                node.Add("m_BakedConvexCollisionMesh", CollisionData.BakedConvexCollisionMesh.ExportYAML());
                node.Add("m_BakedTriangleCollisionMesh", CollisionData.BakedTriangleCollisionMesh.ExportYAML());
            }
            else
            {
                node.Add("m_BakedConvexCollisionMesh", ArrayExtensions.EmptyBytes.ExportYAML());
                node.Add("m_BakedTriangleCollisionMesh", ArrayExtensions.EmptyBytes.ExportYAML());
            }
#warning ???
            node.Add("m_MeshOptimized", 0);

            return(node);
        }
예제 #10
0
        protected override YAMLMappingNode ExportYAMLRoot(IAssetsExporter exporter)
        {
#warning TODO: values acording to read version (current 2017.3.0f3)
            YAMLMappingNode node = base.ExportYAMLRoot(exporter);
            node.AddSerializedVersion(GetSerializedVersion(exporter.Version));
            node.Add("m_SubMeshes", SubMeshes.ExportYAML(exporter));
            node.Add("m_Shapes", Shapes.ExportYAML(exporter));
            node.Add("m_BindPose", BindPoses.ExportYAML(exporter));
#warning ???
            node.Add("m_BoneNames", YAMLSequenceNode.Empty);
            node.Add("m_BoneNameHashes", IsReadBoneNameHashes(exporter.Version) ? BoneNameHashes.ExportYAML(false) : YAMLSequenceNode.Empty);
#warning ???
            node.Add("m_RootBoneName", YAMLScalarNode.Empty);
            node.Add("m_RootBoneNameHash", RootBoneNameHash);
            node.Add("m_MeshCompression", MeshCompression);
            node.Add("m_IsReadable", IsReadable);
            node.Add("m_KeepVertices", KeepVertices);
            node.Add("m_KeepIndices", KeepIndices);
            node.Add("m_IndexBuffer", IsReadIndexBuffer(exporter.Version) ? IndexBuffer.ExportYAML() : YAMLSequenceNode.Empty);
            node.Add("m_Skin", Skin.ExportYAML(exporter));
            node.Add("m_VertexData", VertexData.ExportYAML(exporter));
            node.Add("m_CompressedMesh", CompressedMesh.ExportYAML(exporter));
            node.Add("m_LocalAABB", LocalAABB.ExportYAML(exporter));
            node.Add("m_MeshUsageFlags", MeshUsageFlags);
            if (IsReadCollision(exporter.Version))
            {
                node.Add("m_BakedConvexCollisionMesh", CollisionData.BakedConvexCollisionMesh.ExportYAML());
                node.Add("m_BakedTriangleCollisionMesh", CollisionData.BakedTriangleCollisionMesh.ExportYAML());
            }
            else
            {
                node.Add("m_BakedConvexCollisionMesh", ArrayExtensions.EmptyBytes.ExportYAML());
                node.Add("m_BakedTriangleCollisionMesh", ArrayExtensions.EmptyBytes.ExportYAML());
            }
#warning ???
            node.Add("m_MeshOptimized", 0);

            return(node);
        }
예제 #11
0
        public void BuildModel(RenderResource resource)
        {
            Material materialA = new Material();

            materialA.Visible = true;
            Color colorDiffuseA = Color.FromArgb(unchecked ((int)0xFF0000FF));

            materialA.Diffuse         = colorDiffuseA;
            materialA.TextureFileName = "";
            Materials.Add(materialA);
            Material materialB = new Material();

            materialB.Visible = true;
            Color colorDiffuseB = Color.FromArgb(unchecked ((int)0xFF00FF00));

            materialB.Diffuse         = colorDiffuseB;
            materialB.TextureFileName = "";
            Materials.Add(materialB);

            ModelNode group = new ModelNode();

            group.Name = "group";

            MeshParser meshParser = new MeshParser(ModelName);

            meshParser.BuildMesh(resource);
            foreach (SubMesh subMesh in meshParser.SubMeshes)
            {
                // If the mesh parser knew the total submeshes for the model,
                // then this could be done inside BuildMesh.
                subMesh.MeshIndex = Meshes.Count;
                group.SubMeshIndices.Add(SubMeshes.Count);
                SubMeshes.Add(subMesh);
            }

            Meshes.Add(meshParser.Mesh);
            Groups.Add(group);
            Model = new Model(this);
        }
예제 #12
0
    /// <summary>
    /// Add a quad to the mesh
    /// </summary>
    /// <param name="vertices">List of vertices of the quad (order is important!).</param>
    /// <param name="color">Color to apply to all 4 vertices</param>
    /// <param name="subMesh">Which submesh the quad belongs to</param>
    /// <param name="normal">normal of  each vertex</param>
    public void AddQuad(Vector3[] vertices, Color32 color, SubMeshes subMesh, Vector3 normal)
    {
        if (!CheckVerticeCount(4, vertices.Length))
        {
            return;
        }

        for (int i = 0; i < 4; i++)
        {
            _Vertices.Add(vertices[i]);
            _Colors.Add(color);
            _Normals.Add(normal);
        }

        int vertCount = _Vertices.Count;

        _Triangles[(int)subMesh].Add(vertCount - 4);
        _Triangles[(int)subMesh].Add(vertCount - 3);
        _Triangles[(int)subMesh].Add(vertCount - 1);

        _Triangles[(int)subMesh].Add(vertCount - 1);
        _Triangles[(int)subMesh].Add(vertCount - 3);
        _Triangles[(int)subMesh].Add(vertCount - 2);
    }
예제 #13
0
        internal void Read(EndianBinaryReader reader, ObjectSection section = null)
        {
            reader.SeekCurrent(4);
            BoundingSphere = reader.ReadBoundingSphere();
            int  subMeshCount    = reader.ReadInt32();
            long subMeshesOffset = reader.ReadOffset();
            var  attributes      = ( VertexFormatAttribute )reader.ReadUInt32();
            int  stride          = reader.ReadInt32();
            int  vertexCount     = reader.ReadInt32();
            var  elemItems       = reader.ReadUInt32s(section?.Format == BinaryFormat.X ? 49 : 28);

            Name = reader.ReadString(StringBinaryFormat.FixedLength, 64);

            SubMeshes.Capacity = subMeshCount;
            for (int i = 0; i < subMeshCount; i++)
            {
                reader.ReadAtOffset(subMeshesOffset + i * SubMesh.GetByteSize(section?.Format ?? BinaryFormat.DT),
                                    () =>
                {
                    var subMesh = new SubMesh();
                    subMesh.Read(reader, section);
                    SubMeshes.Add(subMesh);
                });
            }

            // Modern Format
            if (section != null)
            {
                ReadVertexAttributesModern();
            }
            else
            {
                ReadVertexAttributesClassic();
            }

            void ReadVertexAttributesClassic()
            {
                Vector4[] boneWeights = null;
                Vector4[] boneIndices = null;

                for (int i = 0; i < 28; i++)
                {
                    var attribute = ( VertexFormatAttribute )(1 << i);

                    reader.ReadAtOffsetIf((attributes & attribute) != 0, elemItems[i], () =>
                    {
                        switch (attribute)
                        {
                        case VertexFormatAttribute.Vertex:
                            Vertices = reader.ReadVector3s(vertexCount);
                            break;

                        case VertexFormatAttribute.Normal:
                            Normals = reader.ReadVector3s(vertexCount);
                            break;

                        case VertexFormatAttribute.Tangent:
                            Tangents = reader.ReadVector4s(vertexCount);
                            break;

                        case VertexFormatAttribute.UVChannel1:
                            UVChannel1 = reader.ReadVector2s(vertexCount);
                            break;

                        case VertexFormatAttribute.UVChannel2:
                            UVChannel2 = reader.ReadVector2s(vertexCount);
                            break;

                        case VertexFormatAttribute.Color:
                            Colors = reader.ReadColors(vertexCount);
                            break;

                        case VertexFormatAttribute.BoneWeight:
                            boneWeights = reader.ReadVector4s(vertexCount);
                            break;

                        case VertexFormatAttribute.BoneIndex:
                            boneIndices = reader.ReadVector4s(vertexCount);
                            break;

                        default:
                            Console.WriteLine("Unhandled vertex format element: {0}", attribute);
                            break;
                        }
                    });
                }

                if (boneWeights != null && boneIndices != null)
                {
                    BoneWeights = new BoneWeight[vertexCount];
                    for (int i = 0; i < vertexCount; i++)
                    {
                        var weight4 = boneWeights[i];
                        var index4  = Vector4.Divide(boneIndices[i], 3);

                        var boneWeight = new BoneWeight
                        {
                            Weight1 = weight4.X,
                            Weight2 = weight4.Y,
                            Weight3 = weight4.Z,
                            Weight4 = weight4.W,
                            Index1  = ( int )index4.X,
                            Index2  = ( int )index4.Y,
                            Index3  = ( int )index4.Z,
                            Index4  = ( int )index4.W
                        };
                        boneWeight.Validate();

                        BoneWeights[i] = boneWeight;
                    }
                }
            }

            void ReadVertexAttributesModern()
            {
                uint dataOffset     = elemItems[section.Format == BinaryFormat.X ? 27 : 13];
                uint attributeFlags = elemItems[section.Format == BinaryFormat.X ? 42 : 21];

                if (attributeFlags == 2 || attributeFlags == 4)
                {
                    Vertices   = new Vector3[vertexCount];
                    Normals    = new Vector3[vertexCount];
                    Tangents   = new Vector4[vertexCount];
                    UVChannel1 = new Vector2[vertexCount];
                    UVChannel2 = new Vector2[vertexCount];
                    Colors     = new Color[vertexCount];

                    if (attributeFlags == 4)
                    {
                        BoneWeights = new BoneWeight[vertexCount];
                    }

                    bool hasTangents   = false;
                    bool hasUVChannel2 = false;
                    bool hasColors     = false;

                    var vertexReader = section.VertexData.Reader;
                    for (int i = 0; i < vertexCount; i++)
                    {
                        vertexReader.SeekBegin(section.VertexData.DataOffset + dataOffset + stride * i);
                        Vertices[i] = vertexReader.ReadVector3();
                        Normals[i]  = vertexReader.ReadVector3(VectorBinaryFormat.Int16);
                        vertexReader.SeekCurrent(2);
                        Tangents[i]   = vertexReader.ReadVector4(VectorBinaryFormat.Int16);
                        UVChannel1[i] = vertexReader.ReadVector2(VectorBinaryFormat.Half);
                        UVChannel2[i] = vertexReader.ReadVector2(VectorBinaryFormat.Half);
                        Colors[i]     = vertexReader.ReadColor(VectorBinaryFormat.Half);

                        if (attributeFlags == 4)
                        {
                            var boneWeight = new BoneWeight
                            {
                                Weight1 = vertexReader.ReadUInt16() / 32767f,
                                Weight2 = vertexReader.ReadUInt16() / 32767f,
                                Weight3 = vertexReader.ReadUInt16() / 32767f,
                                Weight4 = vertexReader.ReadUInt16() / 32767f,
                                Index1  = vertexReader.ReadByte() / 3,
                                Index2  = vertexReader.ReadByte() / 3,
                                Index3  = vertexReader.ReadByte() / 3,
                                Index4  = vertexReader.ReadByte() / 3
                            };
                            boneWeight.Validate();

                            BoneWeights[i] = boneWeight;
                        }

                        // Normalize normal because precision
                        Normals[i] = Vector3.Normalize(Normals[i]);

                        // Checks to get rid of useless data after reading
                        if (Tangents[i] != Vector4.Zero)
                        {
                            hasTangents = true;
                        }
                        if (UVChannel1[i] != UVChannel2[i])
                        {
                            hasUVChannel2 = true;
                        }
                        if (!Colors[i].Equals(Color.White))
                        {
                            hasColors = true;
                        }
                    }

                    if (!hasTangents)
                    {
                        Tangents = null;
                    }
                    if (!hasUVChannel2)
                    {
                        UVChannel2 = null;
                    }
                    if (!hasColors)
                    {
                        Colors = null;
                    }
                }

                if (Tangents != null)
                {
                    for (int i = 0; i < Tangents.Length; i++)
                    {
                        int direction = Math.Sign(Tangents[i].W);
                        var tangent   =
                            Vector3.Normalize(new Vector3(Tangents[i].X, Tangents[i].Y, Tangents[i].Z));

                        Tangents[i] = new Vector4(tangent, direction);
                    }
                }
            }
        }
        /// <summary>
        /// Returns the submesh for this face based on material info.
        /// </summary>
        /// <param name='f'>The face to find a submesh for.</param>
        public KeyValuePair <IntermediateMaterial, List <int> > FindOrCreateSubMesh(Face f)
        {
            ExternalReference externalRef = null;

            if (Header.Parent != null)
            {
                externalRef = Header.Parent as ExternalReference;
            }

            // Fetch palettes
            MaterialPalette mp = null;

            if (f.MaterialIndex != -1)
            {
                if (externalRef != null)
                {
                    externalRef.Header.MaterialPalettes.TryGetValue(f.MaterialIndex, out mp);
                }

                if (mp == null)
                {
                    Header.MaterialPalettes.TryGetValue(f.MaterialIndex, out mp);
                }

                if (mp == null)
                {
                    Log.WriteError("Could not find material palette: " + f.MaterialIndex);
                }
            }

            TexturePalette mainTex = null;

            if (f.TexturePattern != -1)
            {
                if (externalRef != null)
                {
                    externalRef.Header.TexturePalettes.TryGetValue(f.TexturePattern, out mainTex);
                }

                if (mainTex == null)
                {
                    Header.TexturePalettes.TryGetValue(f.TexturePattern, out mainTex);
                }

                if (mainTex == null)
                {
                    Log.WriteError("Could not find texture pattern: " + f.TexturePattern);
                }
            }

            TexturePalette detailTex = null;

            if (f.DetailTexturePattern != -1)
            {
                if (externalRef != null)
                {
                    externalRef.Header.TexturePalettes.TryGetValue(f.DetailTexturePattern, out detailTex);
                }

                if (mainTex == null)
                {
                    Header.TexturePalettes.TryGetValue(f.DetailTexturePattern, out detailTex);
                }

                if (mainTex == null)
                {
                    Log.WriteError("Could not find detail texture pattern: " + f.DetailTexturePattern);
                }
            }

            // Check locally
            foreach (KeyValuePair <IntermediateMaterial, List <int> > mesh in SubMeshes)
            {
                if (mesh.Key.Equals(mp, mainTex, detailTex, f.Transparency, f.LightMode))
                {
                    return(mesh);
                }
            }

            // Create a new submesh
            IntermediateMaterial im = Header.MaterialBank.FindOrCreateMaterial(f);
            KeyValuePair <IntermediateMaterial, List <int> > newMesh = new KeyValuePair <IntermediateMaterial, List <int> >(im, new List <int>());

            SubMeshes.Add(newMesh);
            return(newMesh);
        }
예제 #15
0
        protected override YAMLMappingNode ExportYAMLRoot(IExportContainer container)
        {
            YAMLMappingNode node = base.ExportYAMLRoot(container);

            node.AddSerializedVersion(ToSerializedVersion(container.ExportVersion));
            if (HasLODData(container.ExportVersion))
            {
                node.Add(LODDataName, LODData.ExportYAML(container));
            }
            else
            {
                if (HasUse16bitIndices(container.ExportVersion))
                {
                    node.Add(Use16BitIndicesName, Use16BitIndices);
                }
                if (IsIndexBufferFirst(container.ExportVersion))
                {
                    node.Add(IndexBufferName, IndexBuffer.ExportYAML());
                }
                node.Add(SubMeshesName, SubMeshes.ExportYAML(container));
            }

            if (HasBlendShapes(container.ExportVersion))
            {
                if (HasBlendChannels(container.ExportVersion))
                {
                    node.Add(ShapesName, Shapes.ExportYAML(container));
                }
                else
                {
                    node.Add(ShapesName, BlendShapes.ExportYAML(container));
                    node.Add(ShapeVerticesName, ShapeVertices.ExportYAML(container));
                }
            }
            if (HasBindPose(container.ExportVersion))
            {
                if (IsBindPoseFirst(container.ExportVersion))
                {
                    node.Add(BindPoseName, BindPose.ExportYAML(container));
                }
            }
            if (HasBoneNameHashes(container.ExportVersion))
            {
                node.Add(BoneNameHashesName, BoneNameHashes.ExportYAML(true));
                node.Add(RootBoneNameHashName, RootBoneNameHash);
            }
            if (HasBonesAABB(container.ExportVersion))
            {
                node.Add(BonesAABBName, BonesAABB.ExportYAML(container));
                node.Add(VariableBoneCountWeightsName, VariableBoneCountWeights.ExportYAML(container));
            }

            if (HasMeshCompression(container.ExportVersion))
            {
                node.Add(MeshCompressionName, (byte)MeshCompression);
            }
            if (HasStreamCompression(container.ExportVersion))
            {
                node.Add(StreamCompressionName, StreamCompression);
            }
            if (HasIsReadable(container.ExportVersion))
            {
                node.Add(IsReadableName, IsReadable);
                node.Add(KeepVerticesName, KeepVertices);
                node.Add(KeepIndicesName, KeepIndices);
            }

            if (HasIndexFormat(container.ExportVersion))
            {
                node.Add(IndexFormatName, (int)IndexFormat);
            }

            if (!HasLODData(container.ExportVersion))
            {
                if (!IsIndexBufferFirst(container.ExportVersion))
                {
                    node.Add(IndexBufferName, IndexBuffer.ExportYAML());
                }
            }

            if (HasVertexData(container.ExportVersion))
            {
                if (!IsOnlyVertexData(container.ExportVersion))
                {
                    if (MeshCompression != MeshCompression.Off)
                    {
                        node.Add(VerticesName, Vertices.ExportYAML(container));
                    }
                }
            }
            else
            {
                node.Add(VerticesName, Vertices.ExportYAML(container));
            }

            if (HasSkin(container.ExportVersion))
            {
                node.Add(SkinName, Skin.ExportYAML(container));
            }
            if (HasBindPose(container.ExportVersion))
            {
                if (!IsBindPoseFirst(container.ExportVersion))
                {
                    node.Add(BindPoseName, BindPose.ExportYAML(container));
                }
            }

            if (HasVertexData(container.ExportVersion))
            {
                if (IsOnlyVertexData(container.ExportVersion))
                {
                    node.Add(VertexDataName, VertexData.ExportYAML(container));
                }
                else
                {
                    if (MeshCompression == MeshCompression.Off)
                    {
                        node.Add(VertexDataName, VertexData.ExportYAML(container));
                    }
                    else
                    {
                        node.Add(UVName, UV.ExportYAML(container));
                        node.Add(UV1Name, UV1.ExportYAML(container));
                        node.Add(TangentsName, Tangents.ExportYAML(container));
                        node.Add(NormalsName, Normals.ExportYAML(container));
                        node.Add(ColorsName, Colors.ExportYAML(container));
                    }
                }
            }
            else
            {
                node.Add(UVName, UV.ExportYAML(container));
                if (HasUV1(container.ExportVersion))
                {
                    node.Add(UV1Name, UV1.ExportYAML(container));
                }
                if (HasTangentSpace(container.ExportVersion))
                {
                    node.Add(TangentSpaceName, Tangents.ExportYAML(container));
                }
                else
                {
                    node.Add(TangentsName, Tangents.ExportYAML(container));
                    node.Add(NormalsName, Normals.ExportYAML(container));
                }
            }

            if (HasCompressedMesh(container.ExportVersion))
            {
                node.Add(CompressedMeshName, CompressedMesh.ExportYAML(container));
            }

            node.Add(LocalAABBName, LocalAABB.ExportYAML(container));
            if (!HasVertexData(container.ExportVersion))
            {
                node.Add(ColorsName, Colors.ExportYAML(container));
            }
            if (HasCollisionTriangles(container.ExportVersion))
            {
                node.Add(CollisionTrianglesName, CollisionTriangles.ExportYAML(true));
                node.Add(CollisionVertexCountName, CollisionVertexCount);
            }
            if (HasMeshUsageFlags(container.ExportVersion))
            {
                node.Add(MeshUsageFlagsName, MeshUsageFlags);
            }

            if (HasCollision(container.ExportVersion))
            {
                node.Add(BakedConvexCollisionMeshName, CollisionData.BakedConvexCollisionMesh.ExportYAML());
                node.Add(BakedTriangleCollisionMeshName, CollisionData.BakedTriangleCollisionMesh.ExportYAML());
            }
            if (HasMeshMetrics(container.ExportVersion))
            {
                node.Add(MeshMetricsName + "[0]", MeshMetrics[0]);
                node.Add(MeshMetricsName + "[1]", MeshMetrics[1]);
            }
            if (HasMeshOptimization(container.ExportVersion, container.ExportFlags))
            {
                if (IsMeshOptimizationFlags(container.ExportVersion))
                {
                    node.Add(MeshOptimizationFlagsName, (int)MeshOptimizationFlags);
                }
                else
                {
                    node.Add(MeshOptimizedName, MeshOptimized);
                }
            }
            if (HasStreamData(container.ExportVersion))
            {
                StreamingInfo streamData = new StreamingInfo(true);
                node.Add(StreamDataName, streamData.ExportYAML(container));
            }
            return(node);
        }
예제 #16
0
            public void Push(SkinnedMeshRenderer renderer)
            {
                var mesh = renderer.sharedMesh;

                if (mesh == null)
                {
                    Debug.LogWarningFormat("{0} has no mesh", renderer.name);
                    return;
                }

                Renderers.Add(renderer);

                var indexOffset     = Positions.Count;
                var boneIndexOffset = Bones.Count;

                Positions.AddRange(mesh.vertices);
                Normals.AddRange(mesh.normals);
                UV.AddRange(mesh.uv);
                Tangents.AddRange(mesh.tangents);

                if (mesh.vertexCount == mesh.boneWeights.Length)
                {
                    BoneWeights.AddRange(mesh.boneWeights.Select(x => AddBoneIndexOffset(x, boneIndexOffset)).ToArray());
                }
                else
                {
                    BoneWeights.AddRange(Enumerable.Range(0, mesh.vertexCount).Select(x => new BoneWeight()).ToArray());
                }

                BindPoses.AddRange(mesh.bindposes);
                Bones.AddRange(renderer.bones);

                for (int i = 0; i < mesh.subMeshCount; ++i)
                {
                    var indices = mesh.GetIndices(i).Select(x => x + indexOffset);
                    var mat     = renderer.sharedMaterials[i];
                    var sameMaterialSubMeshIndex = SubMeshes.FindIndex(x => ReferenceEquals(x.Material, mat));
                    if (sameMaterialSubMeshIndex >= 0)
                    {
                        SubMeshes[sameMaterialSubMeshIndex].Indices.AddRange(indices);
                    }
                    else
                    {
                        SubMeshes.Add(new SubMesh
                        {
                            Indices  = indices.ToList(),
                            Material = mat,
                        });
                    }
                }

                for (int i = 0; i < mesh.blendShapeCount; ++i)
                {
                    var positions = (Vector3[])mesh.vertices.Clone();
                    var normals   = (Vector3[])mesh.normals.Clone();
                    var tangents  = mesh.tangents.Select(x => (Vector3)x).ToArray();

                    mesh.GetBlendShapeFrameVertices(i, 0, positions, normals, tangents);
                    BlendShapes.Add(new BlendShape
                    {
                        VertexOffset = indexOffset,
                        FrameWeight  = mesh.GetBlendShapeFrameWeight(i, 0),
                        Name         = mesh.GetBlendShapeName(i),
                        Positions    = positions,
                        Normals      = normals,
                        Tangents     = tangents,
                    });
                }
            }
예제 #17
0
        public override void Write(AssetWriter writer)
        {
            base.Write(writer);

            if (HasLODData(writer.Version))
            {
                LODData.Write(writer);
            }
            else
            {
                if (HasUse16bitIndices(writer.Version))
                {
                    writer.Write(Use16BitIndices);
                }
                if (IsIndexBufferFirst(writer.Version))
                {
                    IndexBuffer.Write(writer);
                    writer.AlignStream(AlignType.Align4);
                }
                SubMeshes.Write(writer);
            }

            if (HasBlendShapes(writer.Version))
            {
                if (HasBlendChannels(writer.Version))
                {
                    Shapes.Write(writer);
                }
                else
                {
                    BlendShapes.Write(writer);
                    writer.AlignStream(AlignType.Align4);
                    ShapeVertices.Write(writer);
                }
            }
            if (HasBindPose(writer.Version))
            {
                if (IsBindPoseFirst(writer.Version))
                {
                    BindPose.Write(writer);
                }
            }
            if (HasBoneNameHashes(writer.Version))
            {
                BoneNameHashes.Write(writer);
                writer.Write(RootBoneNameHash);
            }
            if (HasBonesAABB(writer.Version))
            {
                BonesAABB.Write(writer);
                VariableBoneCountWeights.Write(writer);
            }

            if (HasMeshCompression(writer.Version))
            {
                writer.Write((byte)MeshCompression);
            }
            if (HasStreamCompression(writer.Version))
            {
                writer.Write(StreamCompression);
            }
            if (HasIsReadable(writer.Version))
            {
                writer.Write(IsReadable);
                writer.Write(KeepVertices);
                writer.Write(KeepIndices);
            }
            if (IsAlignFlags(writer.Version))
            {
                writer.AlignStream(AlignType.Align4);
            }

            if (HasIndexFormat(writer.Version))
            {
                if (IsIndexFormatCondition(writer.Version))
                {
                    if (MeshCompression == MeshCompression.Off)
                    {
                        writer.Write((int)IndexFormat);
                    }
                }
                else
                {
                    writer.Write((int)IndexFormat);
                }
            }

            if (!HasLODData(writer.Version))
            {
                if (!IsIndexBufferFirst(writer.Version))
                {
                    IndexBuffer.Write(writer);
                    writer.AlignStream(AlignType.Align4);
                }
            }

            if (HasVertexData(writer.Version))
            {
                if (!IsOnlyVertexData(writer.Version))
                {
                    if (MeshCompression != MeshCompression.Off)
                    {
                        Vertices.Write(writer);
                    }
                }
            }
            else
            {
                Vertices.Write(writer);
            }

            if (HasSkin(writer.Version))
            {
                Skin.Write(writer);
            }
            if (HasBindPose(writer.Version))
            {
                if (!IsBindPoseFirst(writer.Version))
                {
                    BindPose.Write(writer);
                }
            }

            if (HasVertexData(writer.Version))
            {
                if (IsOnlyVertexData(writer.Version))
                {
                    VertexData.Write(writer);
                }
                else
                {
                    if (MeshCompression == MeshCompression.Off)
                    {
                        VertexData.Write(writer);
                    }
                    else
                    {
                        UV.Write(writer);
                        UV1.Write(writer);
                        Tangents.Write(writer);
                        Normals.Write(writer);
                        Colors.Write(writer);
                    }
                }
            }
            else
            {
                UV.Write(writer);
                if (HasUV1(writer.Version))
                {
                    UV1.Write(writer);
                }
                if (HasTangentSpace(writer.Version))
                {
                    TangentSpace.Write(writer);
                }
                else
                {
                    Tangents.Write(writer);
                    Normals.Write(writer);
                }
            }
            if (IsAlignVertex(writer.Version))
            {
                writer.AlignStream(AlignType.Align4);
            }

            if (HasCompressedMesh(writer.Version))
            {
                CompressedMesh.Write(writer);
            }

            LocalAABB.Write(writer);
            if (!HasVertexData(writer.Version))
            {
                Colors.Write(writer);
            }
            if (HasCollisionTriangles(writer.Version))
            {
                CollisionTriangles.Write(writer);
                writer.Write(CollisionVertexCount);
            }
            if (HasMeshUsageFlags(writer.Version))
            {
                writer.Write(MeshUsageFlags);
            }

            if (HasCollision(writer.Version))
            {
                CollisionData.Write(writer);
            }
            if (HasMeshMetrics(writer.Version))
            {
                writer.Write(MeshMetrics[0]);
                writer.Write(MeshMetrics[1]);
            }
#if UNIVERSAL
            if (HasMeshOptimization(writer.Version, writer.Flags))
            {
                if (IsMeshOptimizationFlags(writer.Version))
                {
                    writer.Write((int)MeshOptimizationFlags);
                }
                else
                {
                    writer.Write(MeshOptimized);
                }
            }
#endif
            if (HasStreamData(writer.Version))
            {
                writer.AlignStream(AlignType.Align4);
                StreamData.Write(writer);
            }
        }
예제 #18
0
        internal void Read(EndianBinaryReader reader, ObjectSection section = null)
        {
            reader.SeekCurrent(4);   // Unused flags

            BoundingSphere = reader.ReadBoundingSphere();

            int  subMeshCount    = reader.ReadInt32();
            long subMeshesOffset = reader.ReadOffset();

            var vertexFormat     = ( VertexFormatAttributes )reader.ReadUInt32();
            int vertexSize       = reader.ReadInt32();
            int vertexCount      = reader.ReadInt32();
            var attributeOffsets = reader.ReadOffsets(20);

            Flags = ( MeshFlags )reader.ReadInt32();

            uint attributeFlags = reader.ReadUInt32();

            reader.SkipNulls(6 * sizeof(uint));

            Name = reader.ReadString(StringBinaryFormat.FixedLength, 64);

            reader.ReadAtOffset(subMeshesOffset, () =>
            {
                SubMeshes.Capacity = subMeshCount;

                for (int i = 0; i < subMeshCount; i++)
                {
                    var subMesh = new SubMesh();
                    subMesh.Read(reader, section);
                    SubMeshes.Add(subMesh);
                }
            });

            // Modern Format
            if ((vertexFormat & VertexFormatAttributes.UsesModernStorage) != 0)
            {
                ReadVertexAttributesModern();
            }

            else
            {
                ReadVertexAttributesClassic();
            }

            void ReadVertexAttributesClassic()
            {
                Vector4[] boneWeights = null;
                Vector4[] boneIndices = null;

                for (int i = 0; i < attributeOffsets.Length; i++)
                {
                    var attribute = ( VertexFormatAttributes )(1 << i);

                    reader.ReadAtOffsetIf((vertexFormat & attribute) != 0, attributeOffsets[i], () =>
                    {
                        switch (attribute)
                        {
                        case VertexFormatAttributes.Position:
                            Positions = reader.ReadVector3s(vertexCount);
                            break;

                        case VertexFormatAttributes.Normal:
                            Normals = reader.ReadVector3s(vertexCount);
                            break;

                        case VertexFormatAttributes.Tangent:
                            Tangents = reader.ReadVector4s(vertexCount);
                            break;

                        case VertexFormatAttributes.TexCoord0:
                            TexCoords0 = reader.ReadVector2s(vertexCount);
                            break;

                        case VertexFormatAttributes.TexCoord1:
                            TexCoords1 = reader.ReadVector2s(vertexCount);
                            break;

                        case VertexFormatAttributes.TexCoord2:
                            TexCoords2 = reader.ReadVector2s(vertexCount);
                            break;

                        case VertexFormatAttributes.TexCoord3:
                            TexCoords3 = reader.ReadVector2s(vertexCount);
                            break;

                        case VertexFormatAttributes.Color0:
                            Colors0 = reader.ReadColors(vertexCount);
                            break;

                        case VertexFormatAttributes.Color1:
                            Colors1 = reader.ReadColors(vertexCount);
                            break;

                        case VertexFormatAttributes.BoneWeight:
                            boneWeights = reader.ReadVector4s(vertexCount);
                            break;

                        case VertexFormatAttributes.BoneIndex:
                            boneIndices = reader.ReadVector4s(vertexCount);
                            break;

                        default:
                            Console.WriteLine("Unhandled vertex format element: {0}", attribute);
                            break;
                        }
                    });
                }

                if (boneWeights == null || boneIndices == null)
                {
                    return;
                }

                BoneWeights = new BoneWeight[vertexCount];

                for (int i = 0; i < vertexCount; i++)
                {
                    var weight4 = boneWeights[i];
                    var index4  = Vector4.Divide(boneIndices[i], 3);

                    var boneWeight = new BoneWeight
                    {
                        Weight1 = weight4.X,
                        Weight2 = weight4.Y,
                        Weight3 = weight4.Z,
                        Weight4 = weight4.W,
                        Index1  = ( int )index4.X,
                        Index2  = ( int )index4.Y,
                        Index3  = ( int )index4.Z,
                        Index4  = ( int )index4.W
                    };

                    boneWeight.Validate();

                    BoneWeights[i] = boneWeight;
                }
            }

            void ReadVertexAttributesModern()
            {
                Positions  = new Vector3[vertexCount];
                Normals    = new Vector3[vertexCount];
                Tangents   = new Vector4[vertexCount];
                TexCoords0 = new Vector2[vertexCount];
                TexCoords1 = new Vector2[vertexCount];

                if (attributeFlags == 10)
                {
                    TexCoords2 = new Vector2[vertexCount];
                    TexCoords3 = new Vector2[vertexCount];
                }
                else if (attributeFlags == 6)
                {
                    TexCoords2 = new Vector2[vertexCount];
                }

                Colors0 = new Color[vertexCount];

                if (attributeFlags == 4)
                {
                    BoneWeights = new BoneWeight[vertexCount];
                }

                bool hasTangents = false;

                EndianBinaryReader vertexReader;
                long baseOffset;

                if (section != null)
                {
                    vertexReader = section.VertexData.Reader;
                    baseOffset   = section.VertexData.DataOffset;
                }
                else
                {
                    vertexReader = reader;
                    baseOffset   = reader.BaseOffset;
                }

                long current = reader.Position;

                for (int i = 0; i < vertexCount; i++)
                {
                    vertexReader.SeekBegin(baseOffset + attributeOffsets[13] + vertexSize * i);

                    Positions[i] = vertexReader.ReadVector3();
                    Normals[i]   = vertexReader.ReadVector3(VectorBinaryFormat.Int16);
                    vertexReader.SeekCurrent(2);
                    Tangents[i]   = vertexReader.ReadVector4(VectorBinaryFormat.Int16);
                    TexCoords0[i] = vertexReader.ReadVector2(VectorBinaryFormat.Half);
                    TexCoords1[i] = vertexReader.ReadVector2(VectorBinaryFormat.Half);

                    if (attributeFlags == 10)
                    {
                        TexCoords2[i] = vertexReader.ReadVector2(VectorBinaryFormat.Half);
                        TexCoords3[i] = vertexReader.ReadVector2(VectorBinaryFormat.Half);
                    }
                    else if (attributeFlags == 6)
                    {
                        TexCoords2[i] = vertexReader.ReadVector2(VectorBinaryFormat.Half);
                    }

                    Colors0[i] = vertexReader.ReadColor(VectorBinaryFormat.Half);

                    if (attributeFlags == 4)
                    {
                        var boneWeight = new BoneWeight
                        {
                            Weight1 = vertexReader.ReadUInt16() / 32767f,
                            Weight2 = vertexReader.ReadUInt16() / 32767f,
                            Weight3 = vertexReader.ReadUInt16() / 32767f,
                            Weight4 = vertexReader.ReadUInt16() / 32767f,
                            Index1  = vertexReader.ReadByte() / 3,
                            Index2  = vertexReader.ReadByte() / 3,
                            Index3  = vertexReader.ReadByte() / 3,
                            Index4  = vertexReader.ReadByte() / 3
                        };

                        boneWeight.Validate();

                        BoneWeights[i] = boneWeight;
                    }

                    // Normalize normal because precision
                    Normals[i] = Vector3.Normalize(Normals[i]);

                    // Checks to get rid of useless data after reading
                    if (Tangents[i] != Vector4.Zero)
                    {
                        hasTangents = true;
                    }
                }

                if (!hasTangents)
                {
                    Tangents = null;
                }

                reader.SeekBegin(current);
            }

            if (Tangents == null)
            {
                return;
            }

            for (int i = 0; i < Tangents.Length; i++)
            {
                int direction = Math.Sign(Tangents[i].W);
                var tangent   = Vector3.Normalize(new Vector3(Tangents[i].X, Tangents[i].Y, Tangents[i].Z));

                Tangents[i] = new Vector4(tangent, direction);
            }
        }
예제 #19
0
        public MeshIntegrationResult Integrate(MeshEnumerateOption onlyBlendShapeRenderers)
        {
            var mesh = new Mesh();

            if (Positions.Count > ushort.MaxValue)
            {
                Debug.LogFormat("exceed 65535 vertices: {0}", Positions.Count);
                mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
            }

            mesh.vertices     = Positions.ToArray();
            mesh.normals      = Normals.ToArray();
            mesh.uv           = UV.ToArray();
            mesh.tangents     = Tangents.ToArray();
            mesh.boneWeights  = BoneWeights.ToArray();
            mesh.subMeshCount = SubMeshes.Count;
            for (var i = 0; i < SubMeshes.Count; ++i)
            {
                mesh.SetIndices(SubMeshes[i].Indices.ToArray(), MeshTopology.Triangles, i);
            }
            mesh.bindposes = BindPoses.ToArray();

            // blendshape
            switch (onlyBlendShapeRenderers)
            {
            case MeshEnumerateOption.OnlyWithBlendShape:
            {
                AddBlendShapesToMesh(mesh);
                mesh.name = INTEGRATED_MESH_WITH_BLENDSHAPE_NAME;
                break;
            }

            case MeshEnumerateOption.All:
            {
                AddBlendShapesToMesh(mesh);
                mesh.name = INTEGRATED_MESH_ALL_NAME;
                break;
            }

            case MeshEnumerateOption.OnlyWithoutBlendShape:
            {
                mesh.name = INTEGRATED_MESH_WITHOUT_BLENDSHAPE_NAME;
                break;
            }
            }

            // meshName
            var meshNode = new GameObject();

            switch (onlyBlendShapeRenderers)
            {
            case MeshEnumerateOption.OnlyWithBlendShape:
            {
                meshNode.name = INTEGRATED_MESH_WITH_BLENDSHAPE_NAME;
                break;
            }

            case MeshEnumerateOption.OnlyWithoutBlendShape:
            {
                meshNode.name = INTEGRATED_MESH_WITHOUT_BLENDSHAPE_NAME;
                break;
            }

            case MeshEnumerateOption.All:
            {
                meshNode.name = INTEGRATED_MESH_ALL_NAME;
                break;
            }
            }

            var integrated = meshNode.AddComponent <SkinnedMeshRenderer>();

            integrated.sharedMesh      = mesh;
            integrated.sharedMaterials = SubMeshes.Select(x => x.Material).ToArray();
            integrated.bones           = Bones.ToArray();
            Result.IntegratedRenderer  = integrated;
            Result.MeshMap.Integrated  = mesh;
            return(Result);
        }
예제 #20
0
        public void Push(MeshRenderer renderer)
        {
            var meshFilter = renderer.GetComponent <MeshFilter>();

            if (meshFilter == null)
            {
                Debug.LogWarningFormat("{0} has no mesh filter", renderer.name);
                return;
            }
            var mesh = meshFilter.sharedMesh;

            if (mesh == null)
            {
                Debug.LogWarningFormat("{0} has no mesh", renderer.name);
                return;
            }
            Result.SourceMeshRenderers.Add(renderer);
            Result.MeshMap.Sources.Add(mesh);

            var indexOffset     = Positions.Count;
            var boneIndexOffset = Bones.Count;

            Positions.AddRange(mesh.vertices
                               .Select(x => renderer.transform.TransformPoint(x))
                               );
            Normals.AddRange(mesh.normals
                             .Select(x => renderer.transform.TransformVector(x))
                             );
            UV.AddRange(mesh.uv);
            Tangents.AddRange(mesh.tangents
                              .Select(t =>
            {
                var v = renderer.transform.TransformVector(t.x, t.y, t.z);
                return(new Vector4(v.x, v.y, v.z, t.w));
            })
                              );

            var self = renderer.transform;
            var bone = self.parent;

            if (bone == null)
            {
                Debug.LogWarningFormat("{0} is root gameobject.", self.name);
                return;
            }
            var bindpose = bone.worldToLocalMatrix;

            BoneWeights.AddRange(Enumerable.Range(0, mesh.vertices.Length)
                                 .Select(x => new BoneWeight()
            {
                boneIndex0 = Bones.Count,
                weight0    = 1,
            })
                                 );

            BindPoses.Add(bindpose);
            Bones.Add(bone);

            for (int i = 0; i < mesh.subMeshCount && i < renderer.sharedMaterials.Length; ++i)
            {
                var indices = mesh.GetIndices(i).Select(x => x + indexOffset);
                var mat     = renderer.sharedMaterials[i];
                var sameMaterialSubMeshIndex = SubMeshes.FindIndex(x => ReferenceEquals(x.Material, mat));
                if (sameMaterialSubMeshIndex >= 0)
                {
                    SubMeshes[sameMaterialSubMeshIndex].Indices.AddRange(indices);
                }
                else
                {
                    SubMeshes.Add(new SubMesh
                    {
                        Indices  = indices.ToList(),
                        Material = mat,
                    });
                }
            }
        }
예제 #21
0
        public void BuildMesh(RenderResource resource)
        {
            float v = 1.2f;
            float h = 1.0f;

            BasicVertex[] vertices =
            {
                new BasicVertex {
                    X = 0, Y = v, Z = 0
                },
                new BasicVertex {
                    X = -h, Y = 0, Z = h
                },
                new BasicVertex {
                    X = -h, Y = 0, Z = -h
                },
                new BasicVertex {
                    X = h, Y = 0, Z = -h
                },
                new BasicVertex {
                    X = h, Y = 0, Z = h
                },
                new BasicVertex {
                    X = 0, Y = -v, Z = 0
                }
            };

            _vertexList.AddRange(vertices);

            int[] indices =
            {
                0, 1, 2,
                5, 3, 2,
                0, 3, 4,
                5, 1, 4,
                5, 2, 1,
                0, 2, 3,
                5, 4, 3,
                0, 4, 1
            };

            _indexList.AddRange(indices);

            Technique = "DefaultRender";

            Mesh = new MeshPCT(resource, this);

            SubMesh subMeshA = new SubMesh
            {
                Name               = MeshName + "-0",
                MaterialIndex      = 0,
                indexCount         = 12,
                startIndexLocation = 0,
                baseVertexLocation = 0
            };

            SubMeshes.Add(subMeshA);

            SubMesh subMeshB = new SubMesh
            {
                Name               = MeshName + "-1",
                MaterialIndex      = 1,
                indexCount         = 12,
                startIndexLocation = 12,
                baseVertexLocation = 0
            };

            SubMeshes.Add(subMeshB);
        }