Пример #1
0
 private void WriteGroup(int groupIndex, ref int baseIndex, ModelEntity model)
 {
     _streamWriter.WriteLine("g group" + groupIndex);
     _streamWriter.WriteLine("usemtl mtl{0}", model.TexturePage);
     for (var k = 0; k < model.Triangles.Length; k++)
     {
         _streamWriter.WriteLine("f {2}/{2}/{2} {1}/{1}/{1} {0}/{0}/{0}", baseIndex++, baseIndex++, baseIndex++);
     }
 }
Пример #2
0
        private void BindMesh(ModelEntity modelEntity, int index, Matrix4?matrix = null, TextureBinder textureBinder = null, bool updateMeshData = true)
        {
            var mesh = GetMesh(index);

            if (mesh == null)
            {
                return;
            }
            if (updateMeshData)
            {
                var numTriangles = modelEntity.Triangles.Length;
                var elementCount = numTriangles * 3 * 3;
                var baseIndex    = 0;
                var positionList = new float[elementCount];
                var normalList   = new float[elementCount];
                var colorList    = new float[elementCount];
                var uvList       = new float[elementCount];
                for (var t = 0; t < numTriangles; t++)
                {
                    var triangle = modelEntity.Triangles[t];
                    for (var i = 0; i < 3; i++)
                    {
                        var index1 = baseIndex++;
                        var index2 = baseIndex++;
                        var index3 = baseIndex++;

                        var vertex = triangle.Vertices[i];
                        positionList[index1] = vertex.X;
                        positionList[index2] = vertex.Y;
                        positionList[index3] = vertex.Z;

                        var normal = triangle.Normals[i];
                        normalList[index1] = normal.X;
                        normalList[index2] = normal.Y;
                        normalList[index3] = normal.Z;

                        var color = triangle.Colors[i];
                        colorList[index1] = color.R;
                        colorList[index2] = color.G;
                        colorList[index3] = color.B;

                        var uv = triangle.Uv[i];
                        uvList[index1] = uv.X;
                        uvList[index2] = uv.Y;
                        uvList[index3] = uv.Z;
                    }
                }
                mesh.SetData(numTriangles * 3, positionList, normalList, colorList, uvList);
            }
            mesh.WorldMatrix = matrix ?? modelEntity.WorldMatrix;
            if (textureBinder != null)
            {
                mesh.Texture = modelEntity.Texture != null?textureBinder.GetTexture(modelEntity.TexturePage) : 0;
            }
        }
Пример #3
0
        private void WriteModel(ModelEntity model)
        {
            if (model.Texture != null)
            {
                if (_mtlExporter.AddMaterial(model.TexturePage))
                {
                    _pngExporter.Export(model.Texture, model.TexturePage, _selectedPath);
                }
            }
            var worldMatrix = model.WorldMatrix;

            foreach (var triangle in model.Triangles)
            {
                var vertexColor0 = string.Empty;
                var vertexColor1 = string.Empty;
                var vertexColor2 = string.Empty;
                var c0           = triangle.Colors[0];
                var c1           = triangle.Colors[1];
                var c2           = triangle.Colors[2];
                if (_experimentalVertexColor)
                {
                    vertexColor0 = string.Format(" {0} {1} {2}", (c0.R).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (c0.G).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (c0.B).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture));
                    vertexColor1 = string.Format(" {0} {1} {2}", (c1.R).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (c1.G).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (c1.B).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture));
                    vertexColor2 = string.Format(" {0} {1} {2}", (c2.R).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (c2.G).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (c2.B).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture));
                }
                var v0 = Vector3.TransformPosition(triangle.Vertices[0], worldMatrix);
                var v1 = Vector3.TransformPosition(triangle.Vertices[1], worldMatrix);
                var v2 = Vector3.TransformPosition(triangle.Vertices[2], worldMatrix);
                _streamWriter.WriteLine("v {0} {1} {2} {3}", (v0.X).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (-v0.Y).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (-v0.Z).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), vertexColor0);
                _streamWriter.WriteLine("v {0} {1} {2} {3}", (v1.X).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (-v1.Y).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (-v1.Z).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), vertexColor1);
                _streamWriter.WriteLine("v {0} {1} {2} {3}", (v2.X).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (-v2.Y).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (-v2.Z).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), vertexColor2);
            }
            foreach (var triangle in model.Triangles)
            {
                var n0 = Vector3.TransformNormal(triangle.Normals[0], worldMatrix);
                var n1 = Vector3.TransformNormal(triangle.Normals[1], worldMatrix);
                var n2 = Vector3.TransformNormal(triangle.Normals[2], worldMatrix);
                _streamWriter.WriteLine("vn {0} {1} {2}", (n0.X).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (-n0.Y).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (-n0.Z).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture));
                _streamWriter.WriteLine("vn {0} {1} {2}", (n1.X).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (-n1.Y).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (-n1.Z).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture));
                _streamWriter.WriteLine("vn {0} {1} {2}", (n2.X).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (-n2.Y).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (-n2.Z).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture));
            }
            foreach (var triangle in model.Triangles)
            {
                var uv0 = triangle.Uv[0];
                var uv1 = triangle.Uv[1];
                var uv2 = triangle.Uv[2];
                _streamWriter.WriteLine("vt {0} {1}", uv0.X.ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (1f - uv0.Y).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture));
                _streamWriter.WriteLine("vt {0} {1}", uv1.X.ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (1f - uv1.Y).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture));
                _streamWriter.WriteLine("vt {0} {1}", uv2.X.ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture), (1f - uv2.Y).ToString(GeomUtils.FloatFormat, CultureInfo.InvariantCulture));
            }
        }
Пример #4
0
        private void ProccessPrimitive(BinaryReader reader, List <ModelEntity> modelEntities, int modelIndex)
        {
            var triangles              = new List <Triangle>();
            var nextPrimitivePointer   = reader.ReadUInt32() * 4;
            var primitiveHeaderPointer = reader.ReadUInt32() * 4;
            var typeCountMapped        = reader.ReadUInt32();
            var mapped    = typeCountMapped >> 0x1F & 0x1;
            var typeCount = typeCountMapped & 0x1F;

            for (var j = 0; j < typeCount; j++)
            {
                var primitiveType    = reader.ReadUInt16();
                var dataType         = reader.ReadUInt16();
                var developerId      = (dataType & 0xF000) >> 0xC;
                var category         = (dataType & 0xF00) >> 0x8; //0: Polygon data 1: Shared polygon data 2: Image data 3: Animation data 4: MIMe data 5: Ground dat
                var driver           = dataType & 0xFF;
                var dataCountAndSize = reader.ReadUInt32();
                var flag             = (dataCountAndSize & 0x80000000) >> 0x1F;
                var dataCount        = (dataCountAndSize & 0x3FFF0000) >> 0x10;
                var dataSize         = dataCountAndSize & 0xFFFF;
                var polygonIndex     = reader.ReadUInt32() * 4;
                if (category == 0)
                {
                    ProcessNonSharedPrimitiveData(triangles, reader, driver, primitiveType, primitiveHeaderPointer, nextPrimitivePointer, polygonIndex, dataCount);
                }
            }
            var modelEntity = new ModelEntity();

            modelEntity.Triangles  = triangles.ToArray();
            modelEntity.HasColors  = true;
            modelEntity.HasNormals = true;
            modelEntity.HasUvs     = false;
            modelEntities.Add(modelEntity);
            if (nextPrimitivePointer < 1000)
            {
                reader.BaseStream.Seek(_offset + nextPrimitivePointer, SeekOrigin.Begin);
                ProccessPrimitive(reader, modelEntities, modelIndex);
            }
        }
Пример #5
0
        private RootEntity ParsePMD(BinaryReader reader)
        {
            var primPoint = reader.ReadUInt32();
            var vertPoint = reader.ReadUInt32();
            var nObj      = reader.ReadUInt32();

            if (nObj < 1 || nObj > 4000)
            {
                return(null);
            }
            var models = new List <ModelEntity>();

            for (var o = 0; o < nObj; o++)
            {
                var model     = new ModelEntity();
                var triangles = new List <Triangle>();
                var nPointers = reader.ReadUInt32();
                if (nPointers < 1 || nPointers > 4000)
                {
                    return(null);
                }
                for (var p = 0; p < nPointers; p++)
                {
                    var position = reader.BaseStream.Position;
                    var pointer  = reader.ReadUInt32();
                    reader.BaseStream.Seek(_offset + pointer, SeekOrigin.Begin);
                    var nPacket = reader.ReadUInt16();
                    if (nPacket > 4000)
                    {
                        return(null);
                    }
                    var primType = reader.ReadUInt16();
                    if (primType > 15)
                    {
                        return(null);
                    }
                    for (var pk = 0; pk < nPacket; pk++)
                    {
                        switch (primType)
                        {
                        case 0x00:
                            triangles.Add(ReadPolyFT3(reader));
                            break;

                        case 0x01:
                            triangles.AddRange(ReadPolyFT4(reader));
                            break;

                        case 0x02:
                            triangles.Add(ReadPolyGT3(reader));
                            break;

                        case 0x03:
                            triangles.AddRange(ReadPolyGT4(reader));
                            break;

                        case 0x04:
                            triangles.Add(ReadPolyF3(reader));
                            break;

                        case 0x05:
                            triangles.AddRange(ReadPolyF4(reader));
                            break;

                        case 0x06:
                            triangles.Add(ReadPolyG3(reader));
                            break;

                        case 0x07:
                            triangles.AddRange(ReadPolyG4(reader));
                            break;

                        case 0x08:
                            triangles.Add(ReadPolyFT3(reader, true, _offset + vertPoint));
                            break;

                        case 0x09:
                            triangles.AddRange(ReadPolyFT4(reader, true, _offset + vertPoint));
                            break;

                        case 0x0a:
                            triangles.Add(ReadPolyGT3(reader, true, _offset + vertPoint));
                            break;

                        case 0x0b:
                            triangles.AddRange(ReadPolyGT4(reader, true, _offset + vertPoint));
                            break;

                        case 0x0c:
                            triangles.Add(ReadPolyF3(reader, true, _offset + vertPoint));
                            break;

                        case 0x0d:
                            triangles.AddRange(ReadPolyF4(reader, true, _offset + vertPoint));
                            break;

                        case 0x0e:
                            triangles.Add(ReadPolyG3(reader, true, _offset + vertPoint));
                            break;

                        case 0x0f:
                            triangles.AddRange(ReadPolyG4(reader, true, _offset + vertPoint));
                            break;

                        default:
                            goto EndObject;
                        }
                    }
                    reader.BaseStream.Seek(position + 4, SeekOrigin.Begin);
                }
EndObject:
                model.Triangles = triangles.ToArray();
                models.Add(model);
            }

EndModel:
            if (models.Count > 0)
            {
                var entity = new RootEntity();
                foreach (var model in models)
                {
                    model.ParentEntity = entity;
                }
                entity.ChildEntities = models.ToArray();
                entity.ComputeBounds();
                return(entity);
            }
            return(null);
        }
Пример #6
0
        public void SetupMultipleEntityBatch(RootEntity[] checkedEntities = null, ModelEntity selectedModelEntity = null, RootEntity selectedRootEntity = null, TextureBinder textureBinder = null, bool updateMeshData = true, bool focus = false, bool hasAnimation = false)
        {
            if (selectedModelEntity == null && selectedRootEntity == null)
            {
                return;
            }
            var bounds = focus ? new BoundingBox() : null;

            selectedRootEntity = selectedRootEntity ?? selectedModelEntity.GetRootEntity();

            //count the selected entity
            var modelCount = 1;

            //count checked, excecpt, the selected
            if (checkedEntities != null)
            {
                foreach (var checkedEntity in checkedEntities)
                {
                    if (checkedEntity == selectedRootEntity)
                    {
                        continue;
                    }
                    modelCount += checkedEntity.ChildEntities.Length;
                    if (focus)
                    {
                        bounds.AddPoints(checkedEntity.Bounds3D.Corners);
                    }
                }
            }
            //focus
            if (selectedRootEntity != null)
            {
                foreach (var subEntity in selectedRootEntity.ChildEntities)
                {
                    modelCount++;
                    if (focus)
                    {
                        bounds.AddPoints(subEntity.Bounds3D.Corners);
                    }
                }
            }
            //reset
            ResetModelIndex();
            if (updateMeshData)
            {
                Reset(modelCount);
            }
            //bindings

            //checked entities, except selected root
            if (checkedEntities != null)
            {
                foreach (var entity in checkedEntities)
                {
                    if (entity == selectedRootEntity)
                    {
                        continue;
                    }
                    foreach (ModelEntity modelEntity in entity.ChildEntities)
                    {
                        BindMesh(modelEntity, modelEntity.TempMatrix * modelEntity.WorldMatrix, textureBinder, updateMeshData, modelEntity.InitialVertices, modelEntity.InitialNormals, modelEntity.FinalVertices, modelEntity.FinalNormals, modelEntity.Interpolator);
                    }
                }
            }
            //if not animating
            //if (!hasAnimation)
            //{
            //root entity
            if (selectedRootEntity != null)
            {
                foreach (ModelEntity modelEntity in selectedRootEntity.ChildEntities)
                {
                    BindMesh(modelEntity, modelEntity.TempMatrix * modelEntity.WorldMatrix, textureBinder, updateMeshData, modelEntity.InitialVertices, modelEntity.InitialNormals, modelEntity.FinalVertices, modelEntity.FinalNormals, modelEntity.Interpolator);
                }
            }
            //}
            // do focus
            if (focus)
            {
                _scene.FocusOnBounds(bounds);
            }
        }
Пример #7
0
        private void BindMesh(ModelEntity modelEntity, Matrix4?matrix = null, TextureBinder textureBinder = null, bool updateMeshData = true, Vector3[] initialVertices = null, Vector3[] initialNormals = null, Vector3[] finalVertices = null, Vector3[] finalNormals = null, float?interpolator = null)
        {
            if (!modelEntity.Visible)
            {
                return;
            }
            var mesh = GetMesh(_modelIndex++);

            if (mesh == null)
            {
                return;
            }
            //var rootEntity = modelEntity.ParentEntity as RootEntity; //todo
            mesh.WorldMatrix = matrix ?? modelEntity.WorldMatrix;
            if (updateMeshData)
            {
                var numTriangles = modelEntity.Triangles.Length;
                var elementCount = numTriangles * 3 * 3;
                var baseIndex    = 0;
                var positionList = new float[elementCount];
                var normalList   = new float[elementCount];
                var colorList    = new float[elementCount];
                var uvList       = new float[elementCount];
                for (var t = 0; t < numTriangles; t++)
                {
                    var lastVertex = Vector3.Zero;
                    var lastNormal = Vector3.Zero;
                    var lastColor  = Color.White;
                    var lastUv     = Vector3.Zero;
                    var triangle   = modelEntity.Triangles[t];
                    for (var i = 0; i < 3; i++)
                    {
                        var index1 = baseIndex++;
                        var index2 = baseIndex++;
                        var index3 = baseIndex++;

                        var sourceVertex = triangle.Vertices[i];
                        if (triangle.AttachedIndices != null)
                        {
                            var attachedIndex = triangle.AttachedIndices[i];
                            if (attachedIndex != uint.MaxValue)
                            {
                                if (!_scene.AutoAttach)
                                {
                                    sourceVertex = new Vector3(DiscardValue, DiscardValue, DiscardValue);
                                }
                            }
                        }

                        Vector3 vertex;
                        if (_scene.VibRibbonWireframe && i == 2)
                        {
                            vertex = lastVertex;
                        }
                        else
                        {
                            if (initialVertices != null && finalVertices != null && triangle.OriginalVertexIndices[i] < finalVertices.Length)
                            {
                                var initialVertex = sourceVertex + initialVertices[triangle.OriginalVertexIndices[i]];
                                var finalVertex   = sourceVertex + finalVertices[triangle.OriginalVertexIndices[i]];
                                vertex = Vector3.Lerp(initialVertex, finalVertex, interpolator.GetValueOrDefault());
                            }
                            else
                            {
                                vertex = sourceVertex;
                            }
                        }

                        positionList[index1] = vertex.X;
                        positionList[index2] = vertex.Y;
                        positionList[index3] = vertex.Z;

                        Vector3 normal;
                        if (_scene.VibRibbonWireframe && i == 2)
                        {
                            normal = lastNormal;
                        }
                        else
                        {
                            if (initialNormals != null && finalNormals != null && triangle.OriginalNormalIndices[i] < finalNormals.Length)
                            {
                                var initialNormal = triangle.Normals[i] + initialNormals[triangle.OriginalNormalIndices[i]] / 4096f;
                                var finalNormal   = triangle.Normals[i] + finalNormals[triangle.OriginalNormalIndices[i]] / 4096f;
                                normal = Vector3.Lerp(initialNormal, finalNormal, interpolator.GetValueOrDefault());
                            }
                            else
                            {
                                normal = triangle.Normals[i];
                            }
                        }

                        normalList[index1] = normal.X;
                        normalList[index2] = normal.Y;
                        normalList[index3] = normal.Z;

                        Color color;
                        if (_scene.VibRibbonWireframe && i == 2)
                        {
                            color = lastColor;
                        }
                        else
                        {
                            color = triangle.Colors[i];
                        }
                        colorList[index1] = color.R;
                        colorList[index2] = color.G;
                        colorList[index3] = color.B;

                        Vector3 uv;
                        if (_scene.VibRibbonWireframe && i == 2)
                        {
                            uv = lastUv;
                        }
                        else
                        {
                            uv = triangle.Uv[i];
                        }
                        uvList[index1] = uv.X;
                        uvList[index2] = uv.Y;
                        uvList[index3] = uv.Z;

                        lastVertex = vertex;
                        lastNormal = normal;
                        lastColor  = color;
                        lastUv     = uv;
                    }
                }
                mesh.SetData(numTriangles * 3, positionList, normalList, colorList, uvList);
            }
            if (textureBinder != null)
            {
                mesh.Texture = modelEntity.Texture != null?textureBinder.GetTexture((int)modelEntity.TexturePage) : 0;
            }
        }
Пример #8
0
 public void BindModelBatch(ModelEntity modelEntity, Matrix4 matrix, TextureBinder textureBinder = null, Vector3[] initialVertices = null, Vector3[] initialNormals = null, Vector3[] finalVertices = null, Vector3[] finalNormals = null, float?interpolator = null)
 {
     BindMesh(modelEntity, matrix, textureBinder, finalVertices != null || finalNormals != null, initialVertices, initialNormals, finalVertices, finalNormals, interpolator);
 }
Пример #9
0
 public void BindModelBatch(ModelEntity modelEntity, int index, Matrix4 matrix, TextureBinder textureBinder = null)
 {
     BindMesh(modelEntity, index, matrix, textureBinder);
 }
Пример #10
0
        public void SetupMultipleEntityBatch(RootEntity[] checkedEntities = null, ModelEntity selectedModel = null, RootEntity selectedEntity = null, TextureBinder textureBinder = null, bool updateMeshData = true, bool focus = false)
        {
            var bounds     = focus ? new BoundingBox() : null;
            var modelCount = checkedEntities != null || selectedEntity != null || selectedModel != null ? 1 : 0;

            if (checkedEntities != null)
            {
                foreach (var entity in checkedEntities)
                {
                    if (entity == selectedEntity)
                    {
                        continue;
                    }
                    modelCount += entity.ChildEntities.Length;
                }
            }
            if (selectedEntity != null)
            {
                foreach (var subEntity in selectedEntity.ChildEntities)
                {
                    modelCount++;
                    if (focus)
                    {
                        bounds.AddPoints(subEntity.Bounds3D.Corners);
                    }
                }
            }
            if (updateMeshData)
            {
                Reset(modelCount);
            }
            var modelIndex = 0;

            if (checkedEntities != null)
            {
                foreach (var entity in checkedEntities)
                {
                    if (entity == selectedEntity)
                    {
                        continue;
                    }
                    foreach (var subEntity in entity.ChildEntities)
                    {
                        if (subEntity == selectedModel)
                        {
                            continue;
                        }
                        BindMesh((ModelEntity)subEntity, modelIndex++, null, textureBinder, updateMeshData);
                    }
                }
            }
            if (selectedEntity != null)
            {
                foreach (var subEntity in selectedEntity.ChildEntities)
                {
                    if (subEntity == selectedModel)
                    {
                        continue;
                    }
                    BindMesh((ModelEntity)subEntity, modelIndex++, null, textureBinder, updateMeshData);
                }
            }
            if (selectedModel != null)
            {
                BindMesh(selectedModel, modelIndex, null, textureBinder, updateMeshData);
            }
            if (focus)
            {
                _scene.FocusOnBounds(bounds);
            }
        }