Example #1
0
        public void LoadAnimationData()
        {
            if (m_loadedData) return;

            lock (this)
            {
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyModel::LoadAnimationData");


                MyLog.Default.WriteLine("MyModel.LoadData -> START", LoggingOptions.LOADING_MODELS);
                MyLog.Default.IncreaseIndent(LoggingOptions.LOADING_MODELS);

                MyLog.Default.WriteLine("m_assetName: " + m_assetName, LoggingOptions.LOADING_MODELS);

                //  Read data from model TAG parameter. There are stored vertex positions, triangle indices, vectors, ... everything we need.
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - import data");

                MyLog.Default.WriteLine(String.Format("Importing asset {0}, path: {1}", m_assetName, AssetName), LoggingOptions.LOADING_MODELS);
                try
                {
                    m_importer.ImportData(AssetName);
                }
                catch
                {
                    MyLog.Default.WriteLine(String.Format("Importing asset failed {0}", m_assetName));
                    throw;
                }
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - load tag data");
                Dictionary<string, object> tagData = m_importer.GetTagData();
                if (tagData.Count == 0)
                {
                    throw new Exception(String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName));
                }

                DataVersion = m_importer.DataVersion;

                Animations = (ModelAnimations)tagData[MyImporterConstants.TAG_ANIMATIONS];
                Bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES];

                BoundingBox = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX];
                BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE];
                BoundingBoxSize = BoundingBox.Max - BoundingBox.Min;
                BoundingBoxSizeHalf = BoundingBoxSize / 2.0f;
                Dummies = tagData[MyImporterConstants.TAG_DUMMIES] as Dictionary<string, MyModelDummy>;
                BoneMapping = tagData[MyImporterConstants.TAG_BONE_MAPPING] as VRageMath.Vector3I[];
                if (BoneMapping.Length == 0)
                    BoneMapping = null;

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize);

                m_loadedData = true;

                MyLog.Default.DecreaseIndent(LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("MyModel.LoadAnimationData -> END", LoggingOptions.LOADING_MODELS);

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
            }
        }
Example #2
0
        public bool ExportData(string tagName, ModelAnimations modelAnimations)
        {
            WriteTag(tagName);

            m_writer.Write(modelAnimations.Clips.Count);
            foreach (var clip in modelAnimations.Clips)
            {
                Write(clip);
            }

            m_writer.Write(modelAnimations.Skeleton.Count);
            foreach (var bone in modelAnimations.Skeleton)
            {
                m_writer.Write(bone);
            }

            return true;
        }      
Example #3
0
        //  Sort of lazy-load, where constructor just saves information about what this model should be, but real load is done here - and only one time.
        //  This loads only vertex data, doesn't touch GPU
        //  Can be called from main and background thread
        public void LoadData()
        {
            if (m_loadedData) return;

            lock (this)
            {
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyModel::LoadData");


                MyLog.Default.WriteLine("MyModel.LoadData -> START", LoggingOptions.LOADING_MODELS);
                MyLog.Default.IncreaseIndent(LoggingOptions.LOADING_MODELS);

                MyLog.Default.WriteLine("m_assetName: " + m_assetName, LoggingOptions.LOADING_MODELS);

                //  Read data from model TAG parameter. There are stored vertex positions, triangle indices, vectors, ... everything we need.
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - import data");

                MyLog.Default.WriteLine(String.Format("Importing asset {0}, path: {1}", m_assetName, AssetName), LoggingOptions.LOADING_MODELS);


                string assetForImport = AssetName;
                var fsPath = Path.IsPathRooted(AssetName) ? AssetName : Path.Combine(MyFileSystem.ContentPath, AssetName);
                if (!MyFileSystem.FileExists(fsPath))
                {
                    assetForImport = @"Models\Debug\Error.mwm";
                }

                try
                {
                    m_importer.ImportData(assetForImport);
                }
                catch
                {
                    MyLog.Default.WriteLine(String.Format("Importing asset failed {0}", m_assetName));
                    VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                    VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                    throw;
                }
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                DataVersion = m_importer.DataVersion;

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - load tag data");
                Dictionary<string, object> tagData = m_importer.GetTagData();
                if (tagData.Count == 0)
                {
                    VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                    VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                    throw new Exception(String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName));
                }
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - vertex, normals, texture coords");


                HalfVector4[] vertices = (HalfVector4[])tagData[MyImporterConstants.TAG_VERTICES];

                System.Diagnostics.Debug.Assert(vertices.Length > 0);

                Byte4[] normals = (Byte4[])tagData[MyImporterConstants.TAG_NORMALS];
                m_vertices = new MyCompressedVertexNormal[vertices.Length];
                if (normals.Length > 0)
                {
                    for (int v = 0; v < vertices.Length; v++)
                    {
                        m_vertices[v] = new MyCompressedVertexNormal()
                        {
                            Position = vertices[v],// VF_Packer.PackPosition(ref vertices[v]),
                            Normal = normals[v]//VF_Packer.PackNormalB4(ref normals[v])
                        };
                    }
                }
                else
                {
                    for (int v = 0; v < vertices.Length; v++)
                    {
                        m_vertices[v] = new MyCompressedVertexNormal()
                        {
                            Position = vertices[v],// VF_Packer.PackPosition(ref vertices[v]),
                        };
                    }
                }


                m_verticesCount = vertices.Length;

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - mesh");
                m_meshContainer.Clear();

                if (tagData.ContainsKey(MyImporterConstants.TAG_MESH_PARTS))
                {
                    List<int> indices = new List<int>(GetVerticesCount()); // Default capacity estimation
                    int maxIndex = 0;

                    List<MyMeshPartInfo> meshParts = tagData[MyImporterConstants.TAG_MESH_PARTS] as List<MyMeshPartInfo>;
                    foreach (MyMeshPartInfo meshPart in meshParts)
                    {
                        MyMesh mesh = new MyMesh(meshPart, m_assetName);
                        mesh.IndexStart = indices.Count;
                        mesh.TriCount = meshPart.m_indices.Count / 3;

                        if (m_loadUV && false == m_hasUV)
                        {
                            m_texCoords = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0];
                            m_hasUV = true;
                            m_loadUV = false;
                        }

                        if (meshPart.m_MaterialDesc != null && meshPart.Technique == MyMeshDrawTechnique.GLASS)
                        {
                            GlassData = mesh;

                            HalfVector2[] forLoadingTexCoords0 = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0];
                            List<HalfVector2> neededTexCoords = new List<HalfVector2>();

                            for (int t = 0; t < meshPart.m_indices.Count; t++)
                            {
                                int index = meshPart.m_indices[t];
                                neededTexCoords.Add(forLoadingTexCoords0[index]);
                            }

                            GlassTexCoords = neededTexCoords.ToArray();
                        }

                        System.Diagnostics.Debug.Assert(mesh.TriCount > 0);

                        if (mesh.TriCount == 0)
                        {
                            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                            return;
                        }

                        foreach (var i in meshPart.m_indices)
                        {
                            indices.Add(i);
                            if (i > maxIndex)
                            {
                                maxIndex = i;
                            }
                        }



                        m_meshContainer.Add(mesh);
                    }

                    if (maxIndex <= ushort.MaxValue)
                    {
                        // create 16 bit indices
                        m_Indices_16bit = new ushort[indices.Count];
                        for (int i = 0; i < indices.Count; i++)
                        {
                            m_Indices_16bit[i] = (ushort)indices[i];
                        }
                    }
                    else
                    {
                        // use 32bit indices
                        m_Indices = indices.ToArray();
                    }
                }

                if (tagData.ContainsKey(MyImporterConstants.TAG_MODEL_BVH))
                {
                    m_bvh = new MyQuantizedBvhAdapter(tagData[MyImporterConstants.TAG_MODEL_BVH] as GImpactQuantizedBvh, this);
                }

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - other data");

                Animations = (ModelAnimations)tagData[MyImporterConstants.TAG_ANIMATIONS];
                Bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES];

                BoundingBox = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX];
                BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE];
                BoundingBoxSize = BoundingBox.Max - BoundingBox.Min;
                BoundingBoxSizeHalf = BoundingBoxSize / 2.0f;
                Dummies = tagData[MyImporterConstants.TAG_DUMMIES] as Dictionary<string, MyModelDummy>;
                BoneMapping = tagData[MyImporterConstants.TAG_BONE_MAPPING] as VRageMath.Vector3I[];

                if (tagData.ContainsKey(MyImporterConstants.TAG_MODEL_FRACTURES))
                    ModelFractures = (MyModelFractures)tagData[MyImporterConstants.TAG_MODEL_FRACTURES];

                object patternScale;
                if (tagData.TryGetValue(MyImporterConstants.TAG_PATTERN_SCALE, out patternScale))
                {
                    PatternScale = (float)patternScale;
                }

                if (BoneMapping.Length == 0)
                    BoneMapping = null;

                if (tagData.ContainsKey(MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY))
                {
                    HavokData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY];
                    byte[] tagCollisionData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY];
                    if (tagCollisionData.Length > 0 && HkBaseSystem.IsThreadInitialized)
                    {
                        bool containsSceneData;
                        bool containsDestructionData;
                        List<HkShape> shapesList = new List<HkShape>();
                        if (!HkShapeLoader.LoadShapesListFromBuffer(tagCollisionData, shapesList, out containsSceneData, out containsDestructionData))
                        {
                            MyLog.Default.WriteLine(string.Format("Model {0} - Unable to load collision geometry", AssetName), LoggingOptions.LOADING_MODELS);
                        //Debug.Fail("Collision model was exported in wrong way: " + m_assetName);
                        }

                        if (shapesList.Count > 10)
                            MyLog.Default.WriteLine(string.Format("Model {0} - Found too many collision shapes, only the first 10 will be used", AssetName), LoggingOptions.LOADING_MODELS);

                        if (HavokCollisionShapes != null)
                        {
                            Debug.Fail("Shapes already loaded");
                        }
                        if (shapesList.Count > 0)
                        {
                            HavokCollisionShapes = shapesList.ToArray();
                        }
                        else
                        {
                            MyLog.Default.WriteLine(string.Format("Model {0} - Unable to load collision geometry from file, default collision will be used !", AssetName));
                        }

                        if (containsDestructionData)
                            HavokDestructionData = tagCollisionData;

                        ExportedWrong = !containsSceneData;
                    }
                }


                if (tagData.ContainsKey(MyImporterConstants.TAG_HAVOK_DESTRUCTION))
                {
                    if (((byte[])tagData[MyImporterConstants.TAG_HAVOK_DESTRUCTION]).Length > 0)
                        HavokDestructionData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_DESTRUCTION];
                }

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - copy triangle indices");
                //  Prepare data
                CopyTriangleIndices();
                m_trianglesCount = Triangles.Count();

                //  Remember this numbers as list may be cleared at the end of this method
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

                MyLog.Default.WriteLine("Triangles.Length: " + Triangles.Length, LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("Vertexes.Length: " + GetVerticesCount(), LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("Centered: " + (bool)tagData[MyImporterConstants.TAG_CENTERED], LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("UseChannelTextures: " + (bool)tagData[MyImporterConstants.TAG_USE_CHANNEL_TEXTURES], LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("Length in meters: " + (float)tagData[MyImporterConstants.TAG_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("Rescale to length in meters?: " + (bool)tagData[MyImporterConstants.TAG_RESCALE_TO_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("BoundingBox: " + BoundingBox, LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("BoundingSphere: " + BoundingSphere, LoggingOptions.LOADING_MODELS);

                Stats.PerAppLifetime.MyModelsCount++;
                Stats.PerAppLifetime.MyModelsMeshesCount += m_meshContainer.Count;
                Stats.PerAppLifetime.MyModelsVertexesCount += GetVerticesCount();
                Stats.PerAppLifetime.MyModelsTrianglesCount += Triangles.Length;

                ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize);

                m_loadedData = true;
                m_loadingErrorProcessed = false;
                MyLog.Default.DecreaseIndent(LoggingOptions.LOADING_MODELS);
                MyLog.Default.WriteLine("MyModel.LoadData -> END", LoggingOptions.LOADING_MODELS);

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
            }
        }
Example #4
0
        //  Sort of lazy-load, where constructor just saves information about what this model should be, but real load is done here - and only one time.
        //  This loads only vertex data, doesn't touch GPU
        //  Can be called from main and background thread
        public void LoadData()
        {
            if (m_loadedData) return;
            if (m_loadedContent) return;

            lock (this)
            {
                if (m_loadedData) return;
                if (m_loadedContent) return;

                MyRender.GetRenderProfiler().StartProfilingBlock("MyModel::LoadData");


                MyRender.Log.WriteLine("MyModel.LoadData -> START", LoggingOptions.LOADING_MODELS);
                MyRender.Log.IncreaseIndent(LoggingOptions.LOADING_MODELS);

                MyRender.Log.WriteLine("m_assetName: " + m_assetName, LoggingOptions.LOADING_MODELS);

                //  Read data from model TAG parameter. There are stored vertex positions, triangle indices, vectors, ... everything we need.
                MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - import data");

                string assetForImport = AssetName;
                var fsPath = Path.IsPathRooted(AssetName) ? AssetName : Path.Combine(MyFileSystem.ContentPath, AssetName);
                if (!MyFileSystem.FileExists(fsPath))
                {
                    MyRender.Log.WriteLine("ERROR: Asset " + AssetName + "not exists!");
                    assetForImport = @"Models\Debug\Error.mwm";
                }

                MyRender.Log.WriteLine(String.Format("Importing asset {0}, path: {1}", assetForImport, AssetName), LoggingOptions.LOADING_MODELS);
                try
                {
                    m_importer.ImportData(assetForImport);
                }
                catch
                {
                    MyRender.Log.WriteLine(String.Format("Importing asset failed {0}", m_assetName));
                    throw;
                }
                MyRender.GetRenderProfiler().EndProfilingBlock();

                MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - load tag data");
                Dictionary<string, object> tagData = m_importer.GetTagData();
                if (tagData.Count == 0)
                {
                    throw new Exception(String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName));
                }
                MyRender.GetRenderProfiler().EndProfilingBlock();

                MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - vertex, normals, texture coords");

                object patternScale;
                if (tagData.TryGetValue(MyImporterConstants.TAG_PATTERN_SCALE, out patternScale))
                {
                    PatternScale = (float)patternScale;
                }

                HalfVector4[] vertices = (HalfVector4[])tagData[MyImporterConstants.TAG_VERTICES];

                //Dont assert, it can be animation
                //System.Diagnostics.Debug.Assert(vertices.Length > 0);

                Byte4[] normals = (Byte4[])tagData[MyImporterConstants.TAG_NORMALS];
                m_vertices = new MyCompressedVertexNormal[vertices.Length];
                if (normals.Length > 0)
                {
                    for (int v = 0; v < vertices.Length; v++)
                    {
                        m_vertices[v] = new MyCompressedVertexNormal()
                        {
                            Position = vertices[v],// VF_Packer.PackPosition(ref vertices[v]),
                            Normal = normals[v]//VF_Packer.PackNormalB4(ref normals[v])
                        };
                    }
                }
                else
                {
                    for (int v = 0; v < vertices.Length; v++)
                    {
                        m_vertices[v] = new MyCompressedVertexNormal()
                        {
                            Position = vertices[v],// VF_Packer.PackPosition(ref vertices[v]),
                        };
                    }
                }

                m_verticesCount = vertices.Length;

                HalfVector2[] forLoadingTexCoords0 = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0];
                m_forLoadingTexCoords0 = new HalfVector2[forLoadingTexCoords0.Length];
                for (int t = 0; t < forLoadingTexCoords0.Length; t++)
                {
                    m_forLoadingTexCoords0[t] = forLoadingTexCoords0[t];// new HalfVector2(forLoadingTexCoords0[t]);
                    m_forLoadingTexCoords0[t] = new HalfVector2(m_forLoadingTexCoords0[t].ToVector2() / PatternScale);
                }

                MyRender.GetRenderProfiler().EndProfilingBlock();

                MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - mesh");
                m_meshContainer.Clear();

                if (tagData.ContainsKey(MyImporterConstants.TAG_MESH_PARTS))
                {
                    List<int> indices = new List<int>(GetVerticesCount()); // Default capacity estimation
                    int maxIndex = 0;

                    List<MyMeshPartInfo> meshParts = tagData[MyImporterConstants.TAG_MESH_PARTS] as List<MyMeshPartInfo>;
                    foreach (MyMeshPartInfo meshPart in meshParts)
                    {
                        if (meshPart.m_MaterialDesc != null)
                            MyRenderModels.Materials[meshPart.m_MaterialDesc.MaterialName] = meshPart.m_MaterialDesc;

                        MyRenderMesh mesh = new MyRenderMesh(meshPart, m_assetName);

                        mesh.IndexStart = indices.Count;
                        mesh.TriCount = meshPart.m_indices.Count / 3;

                        System.Diagnostics.Debug.Assert(mesh.TriCount > 0);

                        foreach (var i in meshPart.m_indices)
                        {
                            indices.Add(i);
                            if (i > maxIndex)
                            {
                                maxIndex = i;
                            }
                        }

                        m_meshContainer.Add(mesh);

                        if (meshPart.m_MaterialDesc != null && meshPart.Technique == MyMeshDrawTechnique.GLASS)
                        {
                            float minimumGlassShadow = 0.0f;

                            if (string.IsNullOrEmpty(meshPart.m_MaterialDesc.GlassCW))
                                continue;

                            if (string.IsNullOrEmpty(meshPart.m_MaterialDesc.GlassCCW))
                                continue;

                            var materialCW = MyTransparentMaterials.GetMaterial(meshPart.m_MaterialDesc.GlassCW);
                            var materialCCW = MyTransparentMaterials.GetMaterial(meshPart.m_MaterialDesc.GlassCCW);

                            mesh.GlassDithering = System.Math.Max(materialCW.Color.W, minimumGlassShadow);

                            MyRenderMesh glassMesh = new MyRenderMesh(meshPart, m_assetName);
                            glassMesh.GlassDithering = System.Math.Max(materialCCW.Color.W, minimumGlassShadow);


                            glassMesh.IndexStart = indices.Count;
                            glassMesh.TriCount = meshPart.m_indices.Count / 3;

                            System.Diagnostics.Debug.Assert(glassMesh.TriCount > 0);

                            for (int i = 0; i < meshPart.m_indices.Count; i += 3)
                            {
                                indices.Add(meshPart.m_indices[i + 0]);
                                indices.Add(meshPart.m_indices[i + 2]);
                                indices.Add(meshPart.m_indices[i + 1]);
                            }

                            m_meshContainer.Add(glassMesh);
                        }
                    }

                    if (maxIndex <= ushort.MaxValue)
                    {
                        // create 16 bit indices
                        m_Indices_16bit = new ushort[indices.Count];
                        for (int i = 0; i < indices.Count; i++)
                        {
                            m_Indices_16bit[i] = (ushort)indices[i];
                        }
                    }
                    else
                    {
                        // use 32bit indices
                        m_Indices = indices.ToArray();
                    }

                    m_trianglesCount = indices.Count / 3;
                }


                MyRender.GetRenderProfiler().EndProfilingBlock();

                MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - other data");
                if (MyRenderConstants.RenderQualityProfile.UseNormals && m_forLoadingTexCoords0.Length > 0)
                {
                    var verticesNum = vertices.Length;
                    
                    Byte4[] forLoadingTangents = (Byte4[])tagData[MyImporterConstants.TAG_TANGENTS];
                    Byte4[] forLoadingBitangents = (Byte4[])tagData[MyImporterConstants.TAG_BINORMALS];
                    m_forLoadingTangents = new Byte4[forLoadingTangents.Length];

                    for (int v = 0; v < forLoadingTangents.Length; v++)
                    {
                        var N = VF_Packer.UnpackNormal(m_vertices[v].Normal.PackedValue);
                        var T = VF_Packer.UnpackNormal(forLoadingTangents[v].PackedValue);
                        var B = VF_Packer.UnpackNormal(forLoadingBitangents[v].PackedValue);

                        var tangentSign = new Vector4(T.X, T.Y, T.Z, 0);
                        tangentSign.W = T.Cross(N).Dot(B) < 0 ? -1 : 1;

                        m_forLoadingTangents[v] = VF_Packer.PackTangentSignB4(ref tangentSign);
                    }
                }

                m_specularShininess = (float)tagData[MyImporterConstants.TAG_SPECULAR_SHININESS];
                m_specularPower = (float)tagData[MyImporterConstants.TAG_SPECULAR_POWER];
                m_rescaleFactor = (float)tagData[MyImporterConstants.TAG_RESCALE_FACTOR];

                BoneIndices = (Vector4I[])tagData[MyImporterConstants.TAG_BLENDINDICES];
                BoneWeights = (Vector4[])tagData[MyImporterConstants.TAG_BLENDWEIGHTS];

                Animations = (ModelAnimations)tagData[MyImporterConstants.TAG_ANIMATIONS];
                Bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES];
                
                if(BoneIndices.Length > 0 && Bones.Length > MyRenderConstants.MAX_SHADER_BONES)
                {
                    List<MyMeshPartInfo> meshParts = tagData[MyImporterConstants.TAG_MESH_PARTS] as List<MyMeshPartInfo>;

                    Dictionary<int, int> vertexChanged = new Dictionary<int,int>();
                    for(int p=0; p<meshParts.Count; p++)
                    {
                        var meshPart = meshParts[p];

                        Dictionary<int, int> bonesUsed = new Dictionary<int, int>();

                        int trianglesNum = meshPart.m_indices.Count / 3;
                        for (int i = 0; i < trianglesNum; i++)
                        {
                            for (int j = 0; j < 3; j++)
                            {
                                int index = meshPart.m_indices[i * 3 + j];
                                if(BoneWeights[index].X > 0)
                                    bonesUsed[BoneIndices[index].X] = 1;
                                if (BoneWeights[index].Y > 0)
                                    bonesUsed[BoneIndices[index].Y] = 1;
                                if (BoneWeights[index].Z > 0)
                                    bonesUsed[BoneIndices[index].Z] = 1;
                                if (BoneWeights[index].W > 0)
                                    bonesUsed[BoneIndices[index].W] = 1;
                            }
                        }

                        var partBones = new List<int>(bonesUsed.Keys);
                        partBones.Sort();
                        if (partBones.Count > 0 && partBones[partBones.Count - 1] >= MyRenderConstants.MAX_SHADER_BONES)
                        {
                            for(int i=0; i<partBones.Count; i++)
                            {
                                bonesUsed[partBones[i]] = i;
                            }

                            Dictionary<int, int> vertexTouched = new Dictionary<int, int>();

                            for (int i = 0; i < trianglesNum; i++)
                            {
                                for (int j = 0; j < 3; j++)
                                {
                                    int index = meshPart.m_indices[i * 3 + j];
                                    if(!vertexTouched.ContainsKey(index))
                                    { 
                                        if (BoneWeights[index].X > 0)
                                            BoneIndices[index].X = bonesUsed[BoneIndices[index].X];
                                        if (BoneWeights[index].Y > 0)
                                            BoneIndices[index].Y = bonesUsed[BoneIndices[index].Y];
                                        if (BoneWeights[index].Z > 0)
                                            BoneIndices[index].Z = bonesUsed[BoneIndices[index].Z];
                                        if (BoneWeights[index].W > 0)
                                            BoneIndices[index].W = bonesUsed[BoneIndices[index].W];

                                        vertexTouched[index] = 1;

                                        int changes = 0;
                                        vertexChanged.TryGetValue(index, out changes);
                                        vertexChanged[index] = changes + 1;
                                    }
                                }
                            }

                            m_meshContainer[p].BonesUsed = partBones.ToArray();
                        }
                    }

                    if (vertexChanged.Values.Count > 0)
                        Debug.Assert(vertexChanged.Values.Max() < 2, "Vertex shared between model parts, will likely result in wrong skinning");
                }

                BoundingBox = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX];
                BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE];
                BoundingBoxSize = BoundingBox.Max - BoundingBox.Min;
                BoundingBoxSizeHalf = BoundingBoxSize / 2.0f;
                Dictionary<string, MyModelDummy> Dummies = tagData[MyImporterConstants.TAG_DUMMIES] as Dictionary<string, MyModelDummy>;
                MyRender.GetRenderProfiler().EndProfilingBlock();

                if (tagData.ContainsKey(MyImporterConstants.TAG_LODS))
                {
                    var tagLODs = tagData[MyImporterConstants.TAG_LODS];

                    LODs.Clear();
                    LODs.AddArray((MyLODDescriptor[])tagLODs);

                    foreach (var lodDesc in LODs)
                    {
                        if (!string.IsNullOrEmpty(lodDesc.RenderQuality))
                        {
                            lodDesc.RenderQualityList = new List<int>();
                            string[] qualityStrings = lodDesc.RenderQuality.ToUpper().Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries);
                            foreach (string qs in qualityStrings)
                            {
                                string qs2 = qs.Trim();
                                if (qs2 == "LOW")
                                    lodDesc.RenderQualityList.Add((int)MyRenderQualityEnum.LOW);
                                else
                                    if (qs2 == "NORMAL")
                                        lodDesc.RenderQualityList.Add((int)MyRenderQualityEnum.NORMAL);
                                    else
                                        if (qs2 == "HIGH")
                                            lodDesc.RenderQualityList.Add((int)MyRenderQualityEnum.HIGH);
                                        else
                                            if (qs2 == "EXTREME")
                                                lodDesc.RenderQualityList.Add((int)MyRenderQualityEnum.EXTREME);
                            }
                        }
                    }
                }


                MyRender.Log.WriteLine("Vertexes.Length: " + GetVerticesCount(), LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("Centered: " + (bool)tagData[MyImporterConstants.TAG_CENTERED], LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("UseChannelTextures: " + (bool)tagData[MyImporterConstants.TAG_USE_CHANNEL_TEXTURES], LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("Length in meters: " + (float)tagData[MyImporterConstants.TAG_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("Rescale to length in meters?: " + (bool)tagData[MyImporterConstants.TAG_RESCALE_TO_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("SpecularShininess: " + m_specularShininess, LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("SpecularPower: " + m_specularPower, LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("RescaleFactor: " + m_rescaleFactor, LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("BoundingBox: " + BoundingBox, LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("BoundingSphere: " + BoundingSphere, LoggingOptions.LOADING_MODELS);

                MyPerformanceCounter.PerAppLifetime.MyModelsCount++;
                MyPerformanceCounter.PerAppLifetime.MyModelsMeshesCount += m_meshContainer.Count;
                MyPerformanceCounter.PerAppLifetime.MyModelsVertexesCount += GetVerticesCount();
                MyPerformanceCounter.PerAppLifetime.MyModelsTrianglesCount += m_trianglesCount;

                ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize);

                m_loadedData = true;

                m_importer.Clear();

                MyRender.Log.DecreaseIndent(LoggingOptions.LOADING_MODELS);
                MyRender.Log.WriteLine("MyModel.LoadData -> END", LoggingOptions.LOADING_MODELS);

                MyRender.GetRenderProfiler().EndProfilingBlock();
            }
        }
        public bool UnloadData()
        {
            bool res = m_loadedData;
            m_loadedData = false;
            if (m_bvh != null)
            {
                m_bvh.Close();
                m_bvh = null;
            }

            VRage.Utils.Stats.PerAppLifetime.MyModelsMeshesCount -= m_meshContainer.Count;
            if (m_vertices != null)
                VRage.Utils.Stats.PerAppLifetime.MyModelsVertexesCount -= GetVerticesCount();
            if (Triangles != null)
                VRage.Utils.Stats.PerAppLifetime.MyModelsTrianglesCount -= Triangles.Length;
            if (res)
                VRage.Utils.Stats.PerAppLifetime.MyModelsCount--;

            if (HavokCollisionShapes != null)
            {
                for (int i = 0; i < HavokCollisionShapes.Length; i++)
                {
                    HavokCollisionShapes[i].RemoveReference();
                }
                HavokCollisionShapes = null;
            }

            if (HavokBreakableShapes != null)
            {
                HavokBreakableShapes = null;
            }

            m_vertices = null;
            Triangles = null;
            m_meshContainer.Clear();
            m_Indices_16bit = null;
            m_Indices = null;

            Dummies = null;


            HavokData = null;
            HavokDestructionData = null;

            Animations = null;

            return res;
        }
Example #6
0
        private static bool ExportData(this BinaryWriter writer, string tagName, ref ModelAnimations animations)
        {
            WriteTag(writer, tagName);

            writer.Write(animations.Clips.Count);

            foreach (var clip in animations.Clips)
            {
                writer.Write(clip.Name);
                writer.Write(clip.Duration);
                writer.Write(clip.Bones.Count);

                foreach (var bone in clip.Bones)
                {
                    writer.Write(bone.Name);
                    writer.Write(bone.Keyframes.Count);

                    foreach (var keyframe in bone.Keyframes)
                    {
                        writer.Write(keyframe.Time);
                        var rotation = keyframe.Rotation.ToVector4();
                        writer.WriteVector4(ref rotation);
                        writer.WriteVector3(ref keyframe.Translation);
                    }
                }
            }

            writer.Write(animations.Skeleton.Count);

            foreach (var skeleton in animations.Skeleton)
                writer.Write(skeleton);

            return true;
        }
Example #7
0
        private static ModelAnimations ReadModelAnimations(BinaryReader reader)
        {
            var modelAnimations = new ModelAnimations { Clips = new List<AnimationClip>() };
            var animationCount = reader.ReadInt32();

            for (var i = 0; i < animationCount; i++)
            {
                var clipName = reader.ReadString();
                var duration = reader.ReadDouble();
                var animationClip = new AnimationClip() { Name = clipName, Duration = duration };

                var boneCount = reader.ReadInt32();
                for (var j = 0; j < boneCount; j++)
                {
                    var boneName = reader.ReadString();
                    var bone = new AnimationClip.Bone() { Name = boneName };
                    var keyFrameCount = reader.ReadInt32();

                    for (var k = 0; k < keyFrameCount; k++)
                    {
                        var time = reader.ReadDouble();
                        var vector = ReadVector4(reader);
                        var rotation = new Quaternion(vector.X, vector.Y, vector.Z, vector.W);
                        var translation = ReadVector3(reader);
                        bone.Keyframes.Add(new AnimationClip.Keyframe() { Time = time, Rotation = rotation, Translation = translation });
                    }

                    animationClip.Bones.Add(bone);
                }

                modelAnimations.Clips.Add(animationClip);
            }

            modelAnimations.Skeleton = ReadArrayOfInt(reader).ToList();
            return modelAnimations;
        }
Example #8
0
        public void LoadAnimationData()
        {
            if (m_loadedData) return;

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyModel::LoadAnimationData");


            MyLog.Default.WriteLine("MyModel.LoadData -> START", LoggingOptions.LOADING_MODELS);
            MyLog.Default.IncreaseIndent(LoggingOptions.LOADING_MODELS);

            MyLog.Default.WriteLine("m_assetName: " + m_assetName, LoggingOptions.LOADING_MODELS);

            //  Read data from model TAG parameter. There are stored vertex positions, triangle indices, vectors, ... everything we need.
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - import data");



            MyLog.Default.WriteLine(String.Format("Importing asset {0}, path: {1}", m_assetName, AssetName), LoggingOptions.LOADING_MODELS);
            try
            {
                m_importer.ImportData(AssetName);
            }
            catch
            {
                MyLog.Default.WriteLine(String.Format("Importing asset failed {0}", m_assetName));
                throw;
            }
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - load tag data");
            Dictionary<string, object> tagData = m_importer.GetTagData();
            if (tagData.Count == 0)
            {
                throw new Exception(String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName));
            }

            DataVersion = m_importer.DataVersion;

            Animations = (ModelAnimations)tagData[MyImporterConstants.TAG_ANIMATIONS];
            Bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES];

            BoundingBox = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX];
            BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE];
            BoundingBoxSize = BoundingBox.Max - BoundingBox.Min;
            BoundingBoxSizeHalf = BoundingBoxSize / 2.0f;
            Dummies = tagData[MyImporterConstants.TAG_DUMMIES] as Dictionary<string, MyModelDummy>;
            BoneMapping = tagData[MyImporterConstants.TAG_BONE_MAPPING] as VRageMath.Vector3I[];
            if (BoneMapping.Length == 0)
                BoneMapping = null;

            if (DataVersion < 01050001)
            { //old version of animations. Scaled and rotated
                if (Animations.Clips.Count > 0)
                {
                    var rotationMatrix = Matrix.CreateRotationY(MathHelper.Pi);
                    Matrix invert = Matrix.Invert(rotationMatrix);

                    foreach (var bone in Animations.Clips[0].Bones)
                    {
                        foreach (var kf in bone.Keyframes)
                        {
                            Matrix keyMatrix = Matrix.CreateFromQuaternion(kf.Rotation);
                            keyMatrix.Translation = kf.Translation * 100;

                            keyMatrix = invert * keyMatrix * rotationMatrix;
                            kf.Transform = keyMatrix;
                        }
                    }
                }
            }


            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize);

            m_loadedData = true;

            MyLog.Default.DecreaseIndent(LoggingOptions.LOADING_MODELS);
            MyLog.Default.WriteLine("MyModel.LoadAnimationData -> END", LoggingOptions.LOADING_MODELS);

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }