示例#1
0
        private void mnuImportOBJ_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();

            dlg.DefaultExt = ".obj";
            dlg.Filter     = "Wavefront .OBJ|*.obj";
            if (dlg.ShowDialog().GetValueOrDefault(false))
            {
                RW4ModelSectionView sectionView         = this.DataContext as RW4ModelSectionView;
                VertexFormat        vertexFormatSection = (VertexFormat)sectionView.Model.Sections.First(s => s.TypeCode == SectionTypeCodes.VertexFormat).obj;

                RW4Section section = sectionView.Section;
                SporeMaster.RenderWare4.RW4Mesh meshSection = section.obj as SporeMaster.RenderWare4.RW4Mesh;

                IConverter converter = new WaveFrontOBJConverter();

                RW4Mesh newMesh = converter.Import(meshSection, dlg.FileName);

                meshSection.vertices.vertices.section.obj   = newMesh.vertices.vertices;
                meshSection.triangles.triangles.section.obj = newMesh.triangles.triangles;

                this.DataContext = sectionView;

                section.Changed();
            }
        }
示例#2
0
        private void mnuRecalculateTangent_Click(object sender, RoutedEventArgs e)
        {
            RW4ModelSectionView sectionView = this.DataContext as RW4ModelSectionView;
            RW4Section          section     = sectionView.Section;

            SporeMaster.RenderWare4.RW4Mesh meshSection = section.obj as SporeMaster.RenderWare4.RW4Mesh;

            TangentSolver(meshSection);

            section.Changed();
        }
示例#3
0
        private void CreateUnitModel()
        {
            if (UnitFileEntry.LOD1 != null)
            {
                //get the 3d model to show in this scene
                KeyProperty   lod1  = UnitFileEntry.LOD1;
                DatabaseIndex index = DatabaseManager.Instance.Indices.Find(k => k.InstanceId == lod1.InstanceId && k.GroupContainer == lod1.GroupContainer && k.TypeId == lod1.TypeId);

                if (index != null)
                {
                    RW4Model _rw4model = new RW4Model();
                    using (Stream stream = new MemoryStream(index.GetIndexData(true)))
                    {
                        _rw4model.Read(stream);
                    }

                    RW4Section section = _rw4model.Sections.First(s => s.TypeCode == SectionTypeCodes.Mesh);
                    if (section != null)
                    {
                        SporeMaster.RenderWare4.RW4Mesh mesh = section.obj as SporeMaster.RenderWare4.RW4Mesh;

                        meshMain.TriangleIndices.Clear();
                        meshMain.Positions.Clear();
                        meshMain.Normals.Clear();
                        meshMain.TextureCoordinates.Clear();

                        try
                        {
                            foreach (var v in mesh.vertices.vertices)
                            {
                                meshMain.Positions.Add(new Point3D(v.Position.X, v.Position.Y, v.Position.Z));
                            }
                            foreach (var t in mesh.triangles.triangles)
                            {
                                meshMain.TriangleIndices.Add((int)t.i);
                                meshMain.TriangleIndices.Add((int)t.j);
                                meshMain.TriangleIndices.Add((int)t.k);
                            }
                        }
                        catch { }
                    }

                    if (UnitFileEntry.ModelSize != null)
                    {
                        ScaleTransform3D scaleTransform = new ScaleTransform3D(UnitFileEntry.ModelSize.Value, UnitFileEntry.ModelSize.Value, UnitFileEntry.ModelSize.Value);
                        modelMain.Transform = scaleTransform;
                    }
                }
            }
        }
        public void Export(RW4Mesh mesh, string fileName)
        {
            using (TextWriter writer = File.CreateText(fileName))
            {
                StringBuilder   sb = new StringBuilder();
                IFormatProvider fp = new System.Globalization.CultureInfo("en-US");

                sb.AppendLine("# SimCityPak Wavefront OBJ Exporter");
                sb.AppendFormat(fp, "# File Created: {0} \r\n", DateTime.Now.ToString());
                sb.AppendLine();

                //add vertex coordinates
                foreach (Vertex v in mesh.vertices.vertices)
                {
                    sb.AppendFormat(fp, "v  {0:F12} {1:F12} {2:F12}\r\n", v.Position.X, v.Position.Y, v.Position.Z);
                }
                sb.AppendFormat(fp, "# {0} vertices\r\n", mesh.vertices.vertices.Length);
                sb.AppendLine();

                //add normals
                foreach (Vertex v in mesh.vertices.vertices)
                {
                    sb.AppendFormat(fp, "vn  {0:F12} {1:F12} {2:F12}\r\n", v.Normal.X, v.Normal.Y, v.Normal.Z);
                }
                sb.AppendFormat(fp, "# {0} vertex normals\r\n", mesh.vertices.vertices.Length);
                sb.AppendLine();

                //add texture coordinates
                foreach (Vertex v in mesh.vertices.vertices)
                {
                    sb.AppendFormat(fp, "vt  {0:F12} {1:F12}\r\n", v.TextureCoordinates.X, v.TextureCoordinates.Y);
                }
                sb.AppendFormat(fp, "# {0} texture coordinates\r\n", mesh.vertices.vertices.Length);
                sb.AppendLine();

                //add faces
                foreach (Triangle t in mesh.triangles.triangles)
                {
                    if (t.i != t.j)
                    {
                        sb.AppendFormat(fp, "f  {0} {1} {2}\r\n", t.i + 1, t.j + 1, t.k + 1);
                    }
                }
                sb.AppendFormat(fp, "# {0} faces\r\n", mesh.triangles.triangles.Length);
                sb.AppendLine();

                writer.WriteLine(sb.ToString());
            }
        }
示例#5
0
        void pack(OgreXmlReader src_model, RW4Model model)
        {
            model.FileType = RW4Model.FileTypes.Model;

            RW4Skeleton skel = new RW4Skeleton();

            skel.unk1 = 0x8d6da0;
            skel.mat3 = new Matrices4x3()
            {
                items = new Mat4x3[] { new Mat4x3()
                                       {
                                           m = new float[] {
                                               1.0f, 0.0f, 0.0f, 0.0f,
                                               0.0f, 1.0f, 0.0f, 0.0f,
                                               0.0f, 0.0f, 1.0f, 0.0f
                                           }
                                       } }
            };
            skel.mat4 = new Matrices4x4()
            {
                items = new Mat4x4[] { new Mat4x4()
                                       {
                                           m = new float[] {
/*                1.0f, 0.0f, 0.0f, 0.0f,
 *              0.0f, 1.0f, 0.0f, 0.0f,
 *              0.0f, 0.0f, 1.0f, 0.0f,*/
                                               0.0f, 1.0f, 0.0f, 0.0f,
                                               -1.0f, 0.0f, 0.0f, 0.0f,
                                               0.0f, 0.0f, 1.0f, 0.0f,
                                               0.0f, 0.0f, 0.0f, 0.0f
                                           }
                                       } }
            };
            skel.jointInfo = new RW4HierarchyInfo()
            {
                id    = "skeleton1".FNV(),
                items = new RW4HierarchyInfo.Item[] {
                    new RW4HierarchyInfo.Item {
                        index = 0, name_fnv = "joint1".FNV(), flags = 1, parent = null
                    }
                },
            };

            var anim = new Anim()
            {
                skeleton_id   = skel.jointInfo.id,
                flags         = 3,
                length        = 1.25f,
                channel_names = (from j in skel.jointInfo.items select j.name_fnv).ToArray(),
            };

            anim.channel_frame_pose = new JointPose[, ] {
                {
                    new JointPose {
                        qx   = 0, qy = 0, qz = 0, qs = 1,
                        tx   = 0, ty = 0, tz = 0,
                        sx   = 1, sy = 1, sz = 1,
                        time = 1.25f
                    }
                }
            };

            var mesh = new RW4Mesh()
            {
                vertices  = new RW4VertexArray(),
                triangles = new RW4TriangleArray(),
            };

            mesh.vertices.unk2   = 0; //< ?
            mesh.vertices.format = new VertexFormat()
            {
                blob = RW4Garbage.vertex_format
            };
            mesh.vertices.vertices = new Buffer <Vertex>(0);
            mesh.vertices.vertices.Assign(src_model.vertices);
            mesh.triangles.unk1      = 0; //< ?
            mesh.triangles.triangles = new Buffer <Triangle>(0);
            mesh.triangles.triangles.Assign(src_model.triangles);

            var texture = new Texture()
            {
                width       = 64,
                height      = 64,
                mipmapInfo  = 0x708,
                textureType = Texture.DXT5,
                unk1        = 0,
                texData     = new TextureBlob()
                {
                    blob = new byte[5488]
                }
            };
            var texture_format = new RW4TexMetadata()
            {
                unk_data_1 = RW4Garbage.texture_format_1,
                unk_data_2 = RW4Garbage.texture_format_2,
                texture    = texture
            };
            var meshMaterial = new RWMeshMaterialAssignment()
            {
                mesh = mesh,
                mat  = new RW4TexMetadata[] { texture_format }
            };

            model.AddObject(anim, Anim.type_code);
            model.AddObject(mesh.vertices.format, VertexFormat.type_code);
            model.AddObject(skel.mat4, Matrices4x4.type_code);
            model.AddObject(skel.mat3, Matrices4x3.type_code);
            skel.mat3.section.fixup_offsets.Add(16);   // !?
            model.AddObject(skel, RW4Skeleton.type_code);
            model.AddObject(mesh.triangles.triangles, Buffer <Triangle> .type_code);
            model.AddObject(mesh.triangles, RW4TriangleArray.type_code);
            model.AddObject(mesh, RW4Mesh.type_code);
            model.AddObject(texture_format, RW4TexMetadata.type_code);
            model.AddObject(meshMaterial, RWMeshMaterialAssignment.type_code);
            model.AddObject(skel.jointInfo, RW4HierarchyInfo.type_code);

            model.AddObject(mesh.vertices.vertices, Buffer <Vertex> .type_code);
            model.AddObject(mesh.vertices, RW4VertexArray.type_code);

            model.AddObject(texture.texData, TextureBlob.type_code);
            model.AddObject(texture, Texture.type_code);
        }
        public RW4Mesh Import(RW4Mesh mesh, string fileName)
        {
            Collada141.COLLADA colladaFile = Collada141.COLLADA.Load(fileName);

            //Retrieve relevant information from the original RW4 Mesh
            uint         verticesSectionNumber  = mesh.vertices.vertices.section.Number;
            uint         trianglesSectionNumber = mesh.triangles.triangles.section.Number;
            VertexFormat vertexFormatSection    = (VertexFormat)mesh.model.Sections.First(s => s.TypeCode == SectionTypeCodes.VertexFormat).obj;

            //Get the visual_scene object that contains all the relevant scene information
            Collada141.library_visual_scenes scenes = colladaFile.Items.OfType <Collada141.library_visual_scenes>().First();
            Collada141.visual_scene          scene  = scenes.visual_scene[0];

            //Load the geometries container
            Collada141.library_geometries geometry = colladaFile.Items.OfType <Collada141.library_geometries>().First();

            //Define the lists to which the temporary items can be saved
            List <int>    triangleDefinitions = new List <int>();
            List <Vertex> vertexList          = new List <Vertex>();
            List <string> vertexDefinitions   = new List <string>();

            //create the materials - but only if the material IDs start with "SCP-"
            List <MaterialDefinition> materialDatas = new List <MaterialDefinition>();

            Collada141.library_materials materialLibrary = colladaFile.Items.OfType <Collada141.library_materials>().First();
            if (((Collada141.material)materialLibrary.material[0]).id.StartsWith("SCP-"))
            {
                int materialIndex = 0;
                foreach (Collada141.material mat in materialLibrary.material)
                {
                    string   materialString = mat.id;
                    string[] materialValues = materialString.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);

                    MaterialDefinition mater = new MaterialDefinition()
                    {
                        Index = int.Parse(materialValues[15], CultureInfo.InvariantCulture.NumberFormat),
                        Id    = mat.name,

                        ColorTop      = byte.Parse(materialValues[8], CultureInfo.InvariantCulture.NumberFormat),
                        ColorBottom   = byte.Parse(materialValues[1], CultureInfo.InvariantCulture.NumberFormat),
                        InteriorData1 = byte.Parse(materialValues[7], CultureInfo.InvariantCulture.NumberFormat),
                        InteriorData2 = byte.Parse(materialValues[2], CultureInfo.InvariantCulture.NumberFormat),

                        TopX      = float.Parse(materialValues[3], CultureInfo.InvariantCulture.NumberFormat),
                        TopY      = float.Parse(materialValues[4], CultureInfo.InvariantCulture.NumberFormat),
                        TopHeight = float.Parse(materialValues[5], CultureInfo.InvariantCulture.NumberFormat),
                        TopWidth  = float.Parse(materialValues[6], CultureInfo.InvariantCulture.NumberFormat),

                        BottomX      = float.Parse(materialValues[9], CultureInfo.InvariantCulture.NumberFormat),
                        BottomY      = float.Parse(materialValues[10], CultureInfo.InvariantCulture.NumberFormat),
                        BottomHeight = float.Parse(materialValues[11], CultureInfo.InvariantCulture.NumberFormat),
                        BottomWidth  = float.Parse(materialValues[12], CultureInfo.InvariantCulture.NumberFormat),

                        TilingTopX    = float.Parse(materialValues[13], CultureInfo.InvariantCulture.NumberFormat),
                        TilingTopY    = float.Parse(materialValues[14], CultureInfo.InvariantCulture.NumberFormat),
                        InteriorSizeX = 0, //1 / float.Parse(materialValues[9], CultureInfo.InvariantCulture.NumberFormat),
                        InteriorSizeY = 0  //1 / float.Parse(materialValues[10], CultureInfo.InvariantCulture.NumberFormat)
                    };

                    if (mater.InteriorData1 > 0)
                    {
                        mater.InteriorSizeX = 1;
                        mater.InteriorSizeY = 1;
                    }

                    materialDatas.Add(mater);

                    materialIndex++;
                }

                float[, ,] materialColors = new float[materialDatas.Max(m => m.Index + 1), 4, 4];

                foreach (MaterialDefinition def in materialDatas)
                {
                    materialColors[def.Index, 0, 0] = (float)def.ColorBottom / 256;
                    materialColors[def.Index, 0, 1] = (float)def.ColorTop / 256;
                    materialColors[def.Index, 0, 2] = (float)def.InteriorData1 / 256;
                    materialColors[def.Index, 0, 3] = (float)def.InteriorData2 / 256;

                    materialColors[def.Index, 1, 0] = def.TopX;
                    materialColors[def.Index, 1, 1] = def.TopY;
                    materialColors[def.Index, 1, 2] = def.TopHeight;
                    materialColors[def.Index, 1, 3] = def.TopWidth;

                    materialColors[def.Index, 2, 0] = def.BottomX;
                    materialColors[def.Index, 2, 1] = def.BottomY;
                    materialColors[def.Index, 2, 2] = def.BottomHeight;
                    materialColors[def.Index, 2, 3] = def.BottomWidth;

                    materialColors[def.Index, 3, 0] = def.TilingTopX;
                    materialColors[def.Index, 3, 1] = def.TilingTopY;
                    materialColors[def.Index, 3, 2] = def.InteriorSizeX;
                    materialColors[def.Index, 3, 3] = def.InteriorSizeY;
                }

                //save the materialsbitmap
                MaterialTextureReference texRef = mesh.model.Materials.Where(m => m.Unknown4 == 0).First();


                DatabaseIndex imageIndex = DatabaseManager.Instance.Indices.Find(idx => idx.InstanceId == texRef.TextureInstanceId && idx.TypeId == PropertyConstants.RW4ImageType);
                if (imageIndex != null)
                {
                    using (MemoryStream imageByteStream = new MemoryStream(imageIndex.GetIndexData(true)))
                    {
                        RW4Model model = new RW4Model();
                        model.Read(imageByteStream);

                        RW4Section textureSection = model.Sections.First(s => s.TypeCode == SectionTypeCodes.Texture);
                        Texture    oldSection     = textureSection.obj as Texture;
                        uint       texDataSection = oldSection.texData.section.Number;

                        Texture newTexture = MaterialTextureConverter.SetTexture(materialColors);

                        newTexture.texData.section = new RW4Section()
                        {
                            Number = texDataSection
                        };
                        newTexture.texData.section.obj = new TextureBlob()
                        {
                            blob = newTexture.texData.blob
                        };

                        textureSection.obj = newTexture;

                        SaveRW4Model(imageIndex, model);
                    }
                }
            }

            int elementIndex = 0;

            //Loop through all nodes in the scene to read the information from the geometry and
            foreach (Collada141.node node in scene.node)
            {
                Collada141.instance_geometry geometryInstance = null;
                if (node.instance_geometry != null)
                {
                    geometryInstance = node.instance_geometry[0];
                }
                else if (node.node1 != null)
                {
                    if (node.node1[0].instance_geometry != null)
                    {
                        geometryInstance = node.node1[0].instance_geometry[0];
                    }
                }

                //check if the node contains any geometry - lights will be ignored
                if (geometryInstance != null)
                {
                    Collada141.geometry geo = geometry.geometry.First(g => "#" + g.id == geometryInstance.url);
                    //Collada141.geometry geo = geometry.geometry.First(g => "#" + g.id == node.instance_geometry[0].url);

                    // Collada141.geometry geo = geometry.geometry[0];
                    Collada141.mesh geoMesh = geo.Item as Collada141.mesh;

                    ///get the array of positions for the vertices
                    Collada141.source      src       = geoMesh.source.First(s => "#" + s.id == geoMesh.vertices.input.First(g => g.semantic == "POSITION").source);
                    Collada141.float_array positions = src.Item as Collada141.float_array;

                    foreach (Collada141.triangles triangles in geoMesh.Items)
                    {
                        List <string> localVertexDefinitions = new List <string>();
                        //calculate how many input indices each triangle exists of
                        ulong    triangleIndexSize = triangles.input.Max(t => t.offset) + 1;
                        string[] triangleIndices   = triangles.p.Split(new char[1] {
                            ' '
                        }, StringSplitOptions.RemoveEmptyEntries);

                        for (int i = 0; i < triangleIndices.Length; i += (int)triangleIndexSize)
                        {
                            string readVertexDefinition = string.Empty;

                            for (int j = 0; j < (int)triangleIndexSize; j++)
                            {
                                readVertexDefinition += triangleIndices[i + j] + " ";
                            }
                            readVertexDefinition += elementIndex + " ";
                            if (!vertexDefinitions.Contains(readVertexDefinition))
                            {
                                vertexDefinitions.Add(readVertexDefinition);
                                localVertexDefinitions.Add(readVertexDefinition);
                            }
                            triangleDefinitions.Add(vertexDefinitions.IndexOf(readVertexDefinition));
                        }

                        //create a vertex for each definition
                        for (int i = 0; i < localVertexDefinitions.Count; i++)
                        {
                            Vertex v = new Vertex();
                            v.Element = elementIndex;

                            v.SetSize(vertexFormatSection.VertexSize);

                            //Create vertexcomponents in the new vertex
                            v.VertexComponents = new List <IVertexComponentValue>();
                            foreach (VertexUsage usage in vertexFormatSection.VertexElements)
                            {
                                IVertexComponentValue component = VertexComponentValueFactory.CreateComponent(usage.DeclarationType);
                                component.Usage = usage.Usage;
                                v.VertexComponents.Add(component);
                            }

                            string[] vdef = localVertexDefinitions[i].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);


                            //create vertexcomponents based on
                            int positionIndex = int.Parse(vdef[0]);
                            VertexFloat3Value positionComponent = (VertexFloat3Value)v.VertexComponents.First(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_POSITION && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_FLOAT3);
                            if (positionComponent != null)
                            {
                                positionComponent.X = (float)positions.Values[(positionIndex * 3)];
                                positionComponent.Y = (float)positions.Values[(positionIndex * 3) + 1];
                                positionComponent.Z = (float)positions.Values[(positionIndex * 3) + 2];
                            }

                            Collada141.source      normalSrc = geoMesh.source.First(s => "#" + s.id == triangles.input.First(g => g.semantic == "NORMAL").source);
                            Collada141.float_array normals   = normalSrc.Item as Collada141.float_array;
                            int normalIndex = int.Parse(vdef[1]);
                            VertexUByte4Value normalComponent = (VertexUByte4Value)v.VertexComponents.FirstOrDefault(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_NORMAL && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_UBYTE4);
                            if (normalComponent != null)
                            {
                                normalComponent.X = (byte)((float)normals.Values[normalIndex * 3] * 127.5F + 127.5F);
                                normalComponent.Y = (byte)((float)normals.Values[(normalIndex * 3) + 1] * 127.5F + 127.5F);
                                normalComponent.Z = (byte)((float)normals.Values[(normalIndex * 3) + 2] * 127.5F + 127.5F);
                                normalComponent.W = (byte)(255);
                            }
                            else
                            {
                                //check if there is a different normal component
                                VertexFloat3Value normalComponent2 = (VertexFloat3Value)v.VertexComponents.FirstOrDefault(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_NORMAL && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_FLOAT3);
                                if (normalComponent2 != null)
                                {
                                    normalComponent2.X = (float)normals.Values[normalIndex * 3];
                                    normalComponent2.Y = (float)normals.Values[(normalIndex * 3) + 1];
                                    normalComponent2.Z = (float)normals.Values[(normalIndex * 3) + 2];
                                }
                            }

                            //Get the external tangents
                            IEnumerable <Collada141.InputLocalOffset> tangentInputs = triangles.input.Where(g => g.semantic == "TEXTANGENT");
                            Collada141.source      bottomTangentSrc = geoMesh.source.First(s => "#" + s.id == tangentInputs.ElementAt(0).source);
                            Collada141.float_array bottomTangents   = bottomTangentSrc.Item as Collada141.float_array;
                            int interiorTangentIndex = int.Parse(vdef[3]);

                            IEnumerable <IVertexComponentValue> tangentComponents = v.VertexComponents.Where(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_TANGENT && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_UBYTE4);
                            if (tangentComponents.Count() != 0)
                            {
                                VertexUByte4Value tangentComponent = (VertexUByte4Value)tangentComponents.ElementAt(0);

                                tangentComponent.X = (byte)((float)bottomTangents.Values[interiorTangentIndex * 3] * 127.5F + 127.5F);
                                tangentComponent.Y = (byte)((float)bottomTangents.Values[(interiorTangentIndex * 3) + 1] * 127.5F + 127.5F);
                                tangentComponent.Z = (byte)((float)bottomTangents.Values[(interiorTangentIndex * 3) + 2] * 127.5F + 127.5F);
                                tangentComponent.W = (byte)(255);

                                //Get the internal tangents
                                if (tangentComponents.Count() > 1)
                                {
                                    Collada141.source      internalTangentSrc = geoMesh.source.First(s => "#" + s.id == tangentInputs.ElementAt(1).source);
                                    Collada141.float_array internalTangents   = internalTangentSrc.Item as Collada141.float_array;
                                    interiorTangentIndex = int.Parse(vdef[5]);


                                    VertexUByte4Value internalTangentComponent = (VertexUByte4Value)tangentComponents.ElementAt(1);

                                    internalTangentComponent.X = (byte)((float)internalTangents.Values[interiorTangentIndex * 3] * 127.5F + 127.5F);
                                    internalTangentComponent.Y = (byte)((float)internalTangents.Values[(interiorTangentIndex * 3) + 1] * 127.5F + 127.5F);
                                    internalTangentComponent.Z = (byte)((float)internalTangents.Values[(interiorTangentIndex * 3) + 2] * 127.5F + 127.5F);
                                    internalTangentComponent.W = (byte)(255);
                                }
                            }
                            else
                            {
                                //check for other tangents
                                VertexFloat3Value tangentComponent2 = (VertexFloat3Value)v.VertexComponents.FirstOrDefault(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_TANGENT && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_FLOAT3);
                                if (tangentComponent2 != null)
                                {
                                    tangentComponent2.X = (float)bottomTangents.Values[interiorTangentIndex * 3];
                                    tangentComponent2.Y = (float)bottomTangents.Values[(interiorTangentIndex * 3) + 1];
                                    tangentComponent2.Z = (float)bottomTangents.Values[(interiorTangentIndex * 3) + 2];
                                }
                            }

                            IEnumerable <Collada141.InputLocalOffset> textureCoordinateInputs = triangles.input.Where(g => g.semantic == "TEXCOORD");
                            Collada141.source bottomUVsource = geoMesh.source.First(s => "#" + s.id == textureCoordinateInputs.ElementAt(0).source);
                            Collada141.source topUVsource    = null;
                            if (textureCoordinateInputs.Count() > 1)
                            {
                                topUVsource = geoMesh.source.First(s => "#" + s.id == textureCoordinateInputs.ElementAt(1).source);
                            }
                            else
                            {
                                topUVsource = geoMesh.source.First(s => "#" + s.id == textureCoordinateInputs.ElementAt(0).source);
                            }

                            Collada141.float_array bottomTextureCoordinates = bottomUVsource.Item as Collada141.float_array;
                            Collada141.float_array topTextureCoordinates    = topUVsource.Item as Collada141.float_array;

                            int uvIndex    = int.Parse(vdef[textureCoordinateInputs.ElementAt(0).offset]);
                            int topUvIndex = 0;
                            if (textureCoordinateInputs.Count() > 1)
                            {
                                topUvIndex = int.Parse(vdef[textureCoordinateInputs.ElementAt(1).offset]);
                            }
                            else
                            {
                                topUvIndex = int.Parse(vdef[textureCoordinateInputs.ElementAt(0).offset]);
                            }

                            //Get all the texture elements (should be 2 in the case of a building)
                            IEnumerable <IVertexComponentValue> uvMapComponents = v.VertexComponents.Where(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_TEXCOORD && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_FLOAT4);

                            if (uvMapComponents.Count() != 0)
                            {
                                VertexFloat4Value uvBottomComponent = (VertexFloat4Value)uvMapComponents.ElementAt(0);
                                uvBottomComponent.X = (float)bottomTextureCoordinates.Values[(uvIndex * 3)];
                                uvBottomComponent.Y = 1 - (float)bottomTextureCoordinates.Values[(uvIndex * 3) + 1];
                                uvBottomComponent.Z = (float)topTextureCoordinates.Values[(topUvIndex * 3)];
                                uvBottomComponent.W = 1 - (float)topTextureCoordinates.Values[(topUvIndex * 3) + 1];

                                if (uvMapComponents.Count() > 1)
                                {
                                    VertexFloat4Value uvTopComponent = (VertexFloat4Value)uvMapComponents.ElementAt(1);
                                    uvTopComponent.X = 0;
                                    uvTopComponent.Y = 0;
                                    uvTopComponent.Z = 1;
                                    uvTopComponent.W = 1;
                                }
                            }
                            else
                            {
                                //check for other UVs
                                VertexFloat2Value uvComponent2 = (VertexFloat2Value)v.VertexComponents.FirstOrDefault(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_TEXCOORD && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_FLOAT2);
                                if (uvComponent2 != null)
                                {
                                    uvComponent2.X = (float)bottomTextureCoordinates.Values[uvIndex * 3];
                                    uvComponent2.Y = (float)bottomTextureCoordinates.Values[(uvIndex * 3) + 1];
                                }
                            }


                            VertexD3DColorValue colorComponent = (VertexD3DColorValue)v.VertexComponents.FirstOrDefault(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_COLOR && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_D3DCOLOR);
                            if (triangles.material.StartsWith("SCP"))
                            {
                                //get the index of the material
                                MaterialDefinition  def             = materialDatas.First(m => m.Id == triangles.material);
                                VertexD3DColorValue colorComponent2 = (VertexD3DColorValue)v.VertexComponents.First(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_COLOR && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_D3DCOLOR);
                                if (colorComponent != null)
                                {
                                    //Unused
                                    colorComponent2.A = 0;
                                    //Unused
                                    colorComponent2.R = 0;
                                    //Material index
                                    colorComponent2.G = (byte)def.Index;
                                    //RNG for windows
                                    colorComponent2.B = 84;
                                }

                                //if the item has a defined interior, recalculate the interior UV's
                                if (def.InteriorData1 > 0)
                                {
                                    // IEnumerable<IVertexComponentValue> uvMapComponentInterior = v.VertexComponents.Where(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_TEXCOORD && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_FLOAT4);
                                    //  VertexFloat4Value uvInterior = (VertexFloat4Value)uvMapComponents.ElementAt(0);
                                    // uvInterior.X = (uvInterior.X / def.BottomX);
                                    // uvInterior.Y = (uvInterior.Y / def.TopX);
                                }
                            }

                            if (node.Items != null)
                            {
                                for (int transIndex = node.Items.Length - 1; transIndex >= 0; transIndex--)
                                {
                                    v = ApplyTransformation(v, node.Items[transIndex], node.ItemsElementName[transIndex]);
                                }
                            }

                            vertexList.Add(v);
                        }
                        elementIndex++;
                    }
                }
            }

            mesh.vertices.vertices         = new SporeMaster.RenderWare4.VertexBuffer(vertexList.Count);
            mesh.vertices.vertices.section = new RW4Section()
            {
                Number = verticesSectionNumber
            };
            mesh.vertices.vertexSize = vertexFormatSection.VertexSize;

            for (int i = 0; i < vertexList.Count; i++)
            {
                mesh.vertices.vertices[i] = vertexList[i];
            }

            //mesh.triangles = new RW4TriangleArray();
            mesh.triangles.triangles         = new Buffer <Triangle>(triangleDefinitions.Count / 3);
            mesh.triangles.triangles.section = new RW4Section()
            {
                Number = trianglesSectionNumber
            };


            for (int i = 0; i < triangleDefinitions.Count / 3; i++)
            {
                mesh.triangles.triangles[i] = new Triangle()
                {
                    i = (uint)triangleDefinitions[(i * 3)],
                    j = (uint)triangleDefinitions[(i * 3) + 1],
                    k = (uint)triangleDefinitions[(i * 3) + 2],
                };
            }


            return(mesh);
        }
 public void Export(RW4Mesh mesh, string fileName)
 {
     throw new NotImplementedException();
 }
        public RW4Mesh Import(RW4Mesh mesh, string fileName)
        {
            //Retrieve relevant information from the original RW4 Mesh
            uint         verticesSectionNumber  = mesh.vertices.vertices.section.Number;
            uint         trianglesSectionNumber = mesh.triangles.triangles.section.Number;
            VertexFormat vertexFormatSection    = (VertexFormat)mesh.model.Sections.First(s => s.TypeCode == SectionTypeCodes.VertexFormat).obj;

            using (TextReader reader = File.OpenText(fileName))
            {
                List <Vector3> vertices  = new List <Vector3>();
                List <int[]>   triangles = new List <int[]>();

                List <Vector3> vertexNormals = new List <Vector3>();
                List <Vector3> vertexUVs     = new List <Vector3>();
                List <KeyValuePair <string, Vertex> > uniqueVertices = new List <KeyValuePair <string, Vertex> >();

                while (reader.Peek() != -1)
                {
                    string lastLine = reader.ReadLine();
                    if (lastLine.StartsWith("v "))
                    {
                        //It's a vertex
                        string[] values = lastLine.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        Vector3  vertex = new Vector3(
                            float.Parse(values[1].Trim(), CultureInfo.InvariantCulture.NumberFormat),
                            float.Parse(values[2].Trim(), CultureInfo.InvariantCulture.NumberFormat),
                            float.Parse(values[3].Trim(), CultureInfo.InvariantCulture.NumberFormat)
                            );
                        vertices.Add(vertex);
                    }
                    if (lastLine.StartsWith("vn"))
                    {
                        //It's a vertex normal
                        string[] values       = lastLine.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        Vector3  vertexNormal = new Vector3(
                            float.Parse(values[1].Trim(), CultureInfo.InvariantCulture.NumberFormat),
                            float.Parse(values[2].Trim(), CultureInfo.InvariantCulture.NumberFormat),
                            float.Parse(values[3].Trim(), CultureInfo.InvariantCulture.NumberFormat)
                            );
                        vertexNormals.Add(vertexNormal);
                    }
                    if (lastLine.StartsWith("vt"))
                    {
                        //It's a vertex UV (texture coordinate)
                        string[] values   = lastLine.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        Vector3  vertexUV = new Vector3(
                            float.Parse(values[1].Trim(), CultureInfo.InvariantCulture.NumberFormat),
                            float.Parse(values[2].Trim(), CultureInfo.InvariantCulture.NumberFormat),
                            float.Parse(values[3].Trim(), CultureInfo.InvariantCulture.NumberFormat)
                            );
                        vertexUVs.Add(vertexUV);
                    }
                    if (lastLine.StartsWith("f "))
                    {
                        //It's a face, get all the vertices it consists of
                        string[] values         = lastLine.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        int[]    triangleValues = new int[values.Length - 1];

                        for (int i = 1; i < values.Length; i++)
                        {
                            if (!uniqueVertices.Exists(uvv => uvv.Key == values[i].Trim()))
                            {
                                string[] vertexInfo = values[i].Split('/');
                                int      coord      = int.Parse(vertexInfo[0]);
                                int      uv         = int.Parse(vertexInfo[1]);
                                int      normal     = int.Parse(vertexInfo[2]);

                                Vertex vert = new Vertex();
                                vert.SetSize(vertexFormatSection.VertexSize);
                                vert.VertexComponents = new List <IVertexComponentValue>();
                                foreach (VertexUsage usage in vertexFormatSection.VertexElements)
                                {
                                    IVertexComponentValue component = VertexComponentValueFactory.CreateComponent(usage.DeclarationType);
                                    component.Usage = usage.Usage;
                                    vert.VertexComponents.Add(component);
                                }

                                VertexFloat3Value positionComponent = (VertexFloat3Value)vert.VertexComponents.First(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_POSITION && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_FLOAT3);
                                if (positionComponent != null)
                                {
                                    positionComponent.X = vertices[coord - 1].X;
                                    positionComponent.Y = vertices[coord - 1].Y;
                                    positionComponent.Z = vertices[coord - 1].Z;
                                }
                                VertexUByte4Value normalComponent = (VertexUByte4Value)vert.VertexComponents.First(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_NORMAL && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_UBYTE4);
                                if (normalComponent != null)
                                {
                                    normalComponent.X = (byte)(vertexNormals[normal - 1].X * 127.5F + 127.5F);
                                    normalComponent.Y = (byte)(vertexNormals[normal - 1].Y * 127.5F + 127.5F);
                                    normalComponent.Z = (byte)(vertexNormals[normal - 1].Z * 127.5F + 127.5F);
                                    normalComponent.W = (byte)(255);
                                }
                                VertexFloat4Value uvComponent = (VertexFloat4Value)vert.VertexComponents.First(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_TEXCOORD && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_FLOAT4);
                                uvComponent.X = vertexUVs[uv - 1].X;
                                uvComponent.Y = vertexUVs[uv - 1].Y;
                                uvComponent.Z = 0;
                                uvComponent.W = 0;

                                uniqueVertices.Add(new KeyValuePair <string, Vertex>(values[i], vert));
                            }
                            triangleValues[i - 1] = uniqueVertices.FindIndex(uvv => uvv.Key == values[i]);
                        }

                        if (triangleValues.Length == 4)
                        {
                            int[] triangleDef1 = new int[3];
                            triangleDef1[0] = triangleValues[0];
                            triangleDef1[1] = triangleValues[1];
                            triangleDef1[2] = triangleValues[3];

                            int[] triangleDef2 = new int[3];
                            triangleDef2[0] = triangleValues[1];
                            triangleDef2[1] = triangleValues[2];
                            triangleDef2[2] = triangleValues[3];

                            triangles.Add(triangleDef1);
                            triangles.Add(triangleDef2);
                        }
                        else if (triangleValues.Length == 3)
                        {
                            int[] triangleDef = new int[3];
                            triangleDef[0] = triangleValues[0];
                            triangleDef[1] = triangleValues[1];
                            triangleDef[2] = triangleValues[2];

                            triangles.Add(triangleDef);
                        }
                    }
                }

                //when read fully, set everything

                mesh.vertices.vertices         = new SporeMaster.RenderWare4.VertexBuffer(uniqueVertices.Count);
                mesh.vertices.vertices.section = new RW4Section()
                {
                    Number = verticesSectionNumber
                };
                mesh.vertices.vertexSize = vertexFormatSection.VertexSize;

                for (int i = 0; i < uniqueVertices.Count; i++)
                {
                    mesh.vertices.vertices[i] = uniqueVertices.ElementAt(i).Value;
                }

                //mesh.triangles = new RW4TriangleArray();
                mesh.triangles.triangles         = new Buffer <Triangle>(triangles.Count);
                mesh.triangles.triangles.section = new RW4Section()
                {
                    Number = trianglesSectionNumber
                };


                for (int i = 0; i < triangles.Count; i++)
                {
                    mesh.triangles.triangles[i] = new Triangle()
                    {
                        i = (uint)triangles[i][0],
                        j = (uint)triangles[i][1],
                        k = (uint)triangles[i][2],
                    };
                }
            }
            return(mesh);
        }
示例#9
0
        private void UserControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (this.DataContext != null && this.DataContext.GetType() == typeof(RW4ModelSectionView))
            {
                matDiffuseMain.Brush = new SolidColorBrush(Colors.LightGray);
                RW4ModelSectionView sectionView = this.DataContext as RW4ModelSectionView;

                // listBoxTextures.ItemsSource = sectionView.Model.Sections.Where<RW4Section>(s => s.TypeCode == SectionTypeCodes.Texture);

                RW4Section section = sectionView.Section;
                SporeMaster.RenderWare4.RW4Mesh mesh = section.obj as SporeMaster.RenderWare4.RW4Mesh;

                meshMain.TriangleIndices.Clear();
                meshMain.Positions.Clear();
                meshMain.Normals.Clear();
                meshMain.TextureCoordinates.Clear();


                if (_boundingBox != null)
                {
                    viewPort.Children.Remove(_boundingBox);
                    _boundingBox = null;
                }


                RW4Section bboxSection = sectionView.Model.Sections.FirstOrDefault <RW4Section>(s => s.TypeCode == SectionTypeCodes.BBox);

                try
                {
                    if (mesh != null)
                    {
                        VertexD3DColorValue lastColorValue = null;

                        //separate the mesh into 'chunks' that can be given different textures if necessary
                        foreach (var v in mesh.vertices.vertices)
                        {
                            if (v.VertexComponents.Exists(vc => vc.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_D3DCOLOR))
                            {
                                VertexD3DColorValue colorVal = v.VertexComponents.First(vc => vc.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_D3DCOLOR) as VertexD3DColorValue;
                                if (colorVal != lastColorValue)
                                {
                                    //create a new 'chunk'.
                                    ModelVisual3D newChunckContainer = new ModelVisual3D();
                                    viewPort.Children.Add(newChunckContainer);
                                    GeometryModel3D newChunk = new GeometryModel3D();

                                    //  GeometryContainer.Content.add
                                }
                            }


                            VertexFloat3Value position = v.VertexComponents.First(vc => vc.Usage == D3DDECLUSAGE.D3DDECLUSAGE_POSITION) as VertexFloat3Value;

                            meshMain.Positions.Add(new Point3D(position.X, position.Y, position.Z));

                            IVertexComponentValue normal = v.VertexComponents.First(vc => vc.Usage == D3DDECLUSAGE.D3DDECLUSAGE_NORMAL);
                            if (normal != null)
                            {
                                if (normal is VertexUByte4Value)
                                {
                                    VertexUByte4Value normalValue = normal as VertexUByte4Value;
                                    meshMain.Normals.Add(new Vector3D(
                                                             (((float)normalValue.X) - 127.5f) / 127.5f,
                                                             (((float)normalValue.Y) - 127.5f) / 127.5f,
                                                             (((float)normalValue.Z) - 127.5f) / 127.5f
                                                             ));
                                }
                                else if (normal is VertexFloat3Value)
                                {
                                    VertexFloat3Value normalValue = normal as VertexFloat3Value;
                                    meshMain.Normals.Add(new Vector3D(normalValue.X, normalValue.Y, normalValue.Z));
                                }
                            }

                            IVertexComponentValue textureCoordinates = v.VertexComponents.First(vc => vc.Usage == D3DDECLUSAGE.D3DDECLUSAGE_TEXCOORD);
                            if (textureCoordinates != null)
                            {
                                if (textureCoordinates is VertexFloat2Value)
                                {
                                    VertexFloat2Value textureCoordinatesValue = textureCoordinates as VertexFloat2Value;
                                    meshMain.TextureCoordinates.Add(new System.Windows.Point(textureCoordinatesValue.X, textureCoordinatesValue.Y));
                                }
                                if (textureCoordinates is VertexFloat4Value)
                                {
                                    VertexFloat4Value textureCoordinatesValue = textureCoordinates as VertexFloat4Value;
                                    meshMain.TextureCoordinates.Add(new System.Windows.Point(textureCoordinatesValue.X, textureCoordinatesValue.Y));
                                }
                            }
                        }
                        foreach (var t in mesh.triangles.triangles)
                        {
                            meshMain.TriangleIndices.Add((int)t.i);
                            meshMain.TriangleIndices.Add((int)t.j);
                            meshMain.TriangleIndices.Add((int)t.k);
                        }
                    }
                }
                catch
                {
                }
                viewPort.ZoomExtents();
            }
        }
示例#10
0
        public RW4Mesh Import(RW4Mesh mesh, string fileName)
        {
            Collada141.COLLADA colladaFile = Collada141.COLLADA.Load(fileName);


            //Retrieve relevant information from the original RW4 Mesh
            uint         verticesSectionNumber  = mesh.vertices.vertices.section.Number;
            uint         trianglesSectionNumber = mesh.triangles.triangles.section.Number;
            VertexFormat vertexFormatSection    = (VertexFormat)mesh.model.Sections.First(s => s.TypeCode == SectionTypeCodes.VertexFormat).obj;

            //Get the visual_scene object that contains all the relevant scene information
            Collada141.library_visual_scenes scenes = colladaFile.Items.OfType <Collada141.library_visual_scenes>().First();
            Collada141.visual_scene          scene  = scenes.visual_scene[0];

            //Load the geometries container
            Collada141.library_geometries geometry = colladaFile.Items.OfType <Collada141.library_geometries>().First();

            //Define the lists to which the temporary items can be saved
            List <int>    triangleDefinitions = new List <int>();
            List <Vertex> vertexList          = new List <Vertex>();
            List <string> vertexDefinitions   = new List <string>();

            int elementIndex = 0;

            //Loop through all nodes in the scene to read the information from the geometry and
            foreach (Collada141.node node in scene.node)
            {
                //check if the node contains any geometry - lights will be ignored
                if (node.instance_geometry != null)
                {
                    Collada141.geometry geo = geometry.geometry.First(g => "#" + g.id == node.instance_geometry[0].url);

                    // Collada141.geometry geo = geometry.geometry[0];
                    Collada141.mesh geoMesh = geo.Item as Collada141.mesh;

                    ///get the array of positions for the vertices
                    Collada141.source      src       = geoMesh.source.First(s => "#" + s.id == geoMesh.vertices.input.First(g => g.semantic == "POSITION").source);
                    Collada141.float_array positions = src.Item as Collada141.float_array;

                    foreach (Collada141.triangles triangles in geoMesh.Items)
                    {
                        List <string> localVertexDefinitions = new List <string>();
                        //calculate how many input indices each triangle exists of
                        ulong    triangleIndexSize = triangles.input.Max(t => t.offset) + 1;
                        string[] triangleIndices   = triangles.p.Split(new char[1] {
                            ' '
                        }, StringSplitOptions.RemoveEmptyEntries);

                        for (int i = 0; i < triangleIndices.Length; i += (int)triangleIndexSize)
                        {
                            string readVertexDefinition = string.Empty;

                            for (int j = 0; j < (int)triangleIndexSize; j++)
                            {
                                readVertexDefinition += triangleIndices[i + j] + " ";
                            }
                            readVertexDefinition += elementIndex + " ";
                            if (!vertexDefinitions.Contains(readVertexDefinition))
                            {
                                vertexDefinitions.Add(readVertexDefinition);
                                localVertexDefinitions.Add(readVertexDefinition);
                            }
                            triangleDefinitions.Add(vertexDefinitions.IndexOf(readVertexDefinition));
                        }



                        //create a vertex for each definition
                        for (int i = 0; i < localVertexDefinitions.Count; i++)
                        {
                            Vertex v = new Vertex();
                            v.Element = elementIndex;

                            v.SetSize(vertexFormatSection.VertexSize);

                            //Create vertexcomponents in the new vertex
                            v.VertexComponents = new List <IVertexComponentValue>();
                            foreach (VertexUsage usage in vertexFormatSection.VertexElements)
                            {
                                IVertexComponentValue component = VertexComponentValueFactory.CreateComponent(usage.DeclarationType);
                                component.Usage = usage.Usage;
                                v.VertexComponents.Add(component);
                            }



                            string[] vdef = localVertexDefinitions[i].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                            //create vertexcomponents based on
                            int positionIndex = int.Parse(vdef[0]);
                            VertexFloat3Value positionComponent = (VertexFloat3Value)v.VertexComponents.First(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_POSITION && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_FLOAT3);
                            if (positionComponent != null)
                            {
                                positionComponent.X = (float)positions.Values[(positionIndex * 3)];
                                positionComponent.Y = (float)positions.Values[(positionIndex * 3) + 1];
                                positionComponent.Z = (float)positions.Values[(positionIndex * 3) + 2];
                            }

                            Collada141.source      normalSrc = geoMesh.source.First(s => "#" + s.id == triangles.input.First(g => g.semantic == "NORMAL").source);
                            Collada141.float_array normals   = normalSrc.Item as Collada141.float_array;
                            int normalIndex = int.Parse(vdef[1]);
                            VertexUByte4Value normalComponent = (VertexUByte4Value)v.VertexComponents.First(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_NORMAL && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_UBYTE4);
                            if (normalComponent != null)
                            {
                                normalComponent.X = (byte)((float)normals.Values[normalIndex * 3] * 127.5F + 127.5F);
                                normalComponent.Y = (byte)((float)normals.Values[(normalIndex * 3) + 1] * 127.5F + 127.5F);
                                normalComponent.Z = (byte)((float)normals.Values[(normalIndex * 3) + 2] * 127.5F + 127.5F);
                                normalComponent.W = (byte)(255);
                            }

                            IEnumerable <Collada141.InputLocalOffset> tangentInputs = triangles.input.Where(g => g.semantic == "TEXTANGENT");
                            Collada141.source      bottomTangentSrc = geoMesh.source.First(s => "#" + s.id == tangentInputs.ElementAt(0).source);
                            Collada141.float_array bottomTangents   = bottomTangentSrc.Item as Collada141.float_array;
                            int interiorTangentIndex = int.Parse(vdef[3]);

                            IEnumerable <IVertexComponentValue> tangentComponents = v.VertexComponents.Where(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_TANGENT && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_UBYTE4);
                            VertexUByte4Value tangentComponent = (VertexUByte4Value)tangentComponents.ElementAt(0);

                            tangentComponent.X = (byte)((float)bottomTangents.Values[interiorTangentIndex * 3] * 127.5F + 127.5F);
                            tangentComponent.Y = (byte)((float)bottomTangents.Values[(interiorTangentIndex * 3) + 1] * 127.5F + 127.5F);
                            tangentComponent.Z = (byte)((float)bottomTangents.Values[(interiorTangentIndex * 3) + 2] * 127.5F + 127.5F);
                            tangentComponent.W = (byte)(255);


                            IEnumerable <Collada141.InputLocalOffset> textureCoordinateInputs = triangles.input.Where(g => g.semantic == "TEXCOORD");
                            Collada141.source bottomUVsource = geoMesh.source.First(s => "#" + s.id == textureCoordinateInputs.ElementAt(0).source);
                            Collada141.source topUVsource    = geoMesh.source.First(s => "#" + s.id == textureCoordinateInputs.ElementAt(1).source);

                            Collada141.float_array bottomTextureCoordinates = bottomUVsource.Item as Collada141.float_array;
                            Collada141.float_array topTextureCoordinates    = topUVsource.Item as Collada141.float_array;

                            int uvIndex    = int.Parse(vdef[textureCoordinateInputs.ElementAt(0).offset]);
                            int topUvIndex = int.Parse(vdef[textureCoordinateInputs.ElementAt(1).offset]);

                            //Get all the texture elements (should be 2 in the case of a building)
                            IEnumerable <IVertexComponentValue> uvMapComponents = v.VertexComponents.Where(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_TEXCOORD && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_FLOAT4);

                            VertexFloat4Value uvBottomComponent = (VertexFloat4Value)uvMapComponents.ElementAt(0);
                            uvBottomComponent.X = (float)bottomTextureCoordinates.Values[(uvIndex * 3)];
                            uvBottomComponent.Y = 1 - (float)bottomTextureCoordinates.Values[(uvIndex * 3) + 1];
                            uvBottomComponent.Z = (float)topTextureCoordinates.Values[(topUvIndex * 3)];
                            uvBottomComponent.W = 1 - (float)topTextureCoordinates.Values[(topUvIndex * 3) + 1];

                            if (uvMapComponents.Count() > 1)
                            {
                                VertexFloat4Value uvTopComponent = (VertexFloat4Value)uvMapComponents.ElementAt(1);
                                uvTopComponent.X = 0;
                                uvTopComponent.Y = 0;
                                uvTopComponent.Z = 1;
                                uvTopComponent.W = 1;
                            }


                            VertexD3DColorValue colorComponent = (VertexD3DColorValue)v.VertexComponents.First(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_COLOR && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_D3DCOLOR);
                            if (colorComponent != null)
                            {
                                colorComponent.A = (byte)elementIndex;
                                colorComponent.R = (byte)elementIndex;
                                colorComponent.G = (byte)elementIndex;
                                colorComponent.B = (byte)elementIndex;
                            }

                            if (triangles.material.StartsWith("SCP"))
                            {
                                string   materialString = triangles.material;
                                string[] materialValues = materialString.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);


                                VertexD3DColorValue colorComponent2 = (VertexD3DColorValue)v.VertexComponents.First(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_COLOR && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_D3DCOLOR);
                                if (colorComponent != null)
                                {
                                    colorComponent2.A = byte.Parse(materialValues[7]);
                                    colorComponent2.R = byte.Parse(materialValues[8]);
                                    colorComponent2.G = byte.Parse(materialValues[1]);
                                    colorComponent2.B = byte.Parse(materialValues[2]);
                                }

                                VertexShort4NValue texComponent1 = (VertexShort4NValue)v.VertexComponents.FirstOrDefault(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_TEXCOORD && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_SHORT4N);
                                if (texComponent1 != null)
                                {
                                    texComponent1.X = float.Parse(materialValues[3], CultureInfo.InvariantCulture.NumberFormat);
                                    texComponent1.Y = float.Parse(materialValues[4], CultureInfo.InvariantCulture.NumberFormat);
                                    texComponent1.Z = float.Parse(materialValues[5], CultureInfo.InvariantCulture.NumberFormat);
                                    texComponent1.W = float.Parse(materialValues[6], CultureInfo.InvariantCulture.NumberFormat);
                                }

                                VertexShort4NValue texComponent2 = (VertexShort4NValue)v.VertexComponents.LastOrDefault(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_TEXCOORD && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_SHORT4N);
                                if (texComponent2 != null)
                                {
                                    texComponent2.X = float.Parse(materialValues[9], CultureInfo.InvariantCulture.NumberFormat);
                                    texComponent2.Y = float.Parse(materialValues[10], CultureInfo.InvariantCulture.NumberFormat);
                                    texComponent2.Z = float.Parse(materialValues[11], CultureInfo.InvariantCulture.NumberFormat);
                                    texComponent2.W = float.Parse(materialValues[12], CultureInfo.InvariantCulture.NumberFormat);
                                }

                                VertexFloat4Value uvComponent1 = (VertexFloat4Value)v.VertexComponents.First(c => c.Usage == D3DDECLUSAGE.D3DDECLUSAGE_TEXCOORD && c.DeclarationType == D3DDECLTYPE.D3DDECLTYPE_FLOAT4);
                                if (uvComponent1 != null)
                                {
                                    if (materialValues[2] == "0")
                                    {
                                        uvComponent1.X = uvComponent1.X * float.Parse(materialValues[3], CultureInfo.InvariantCulture.NumberFormat);
                                        uvComponent1.Y = uvComponent1.Y * float.Parse(materialValues[4], CultureInfo.InvariantCulture.NumberFormat);
                                    }
                                    uvComponent1.Z = uvComponent1.Z * float.Parse(materialValues[9], CultureInfo.InvariantCulture.NumberFormat);
                                    uvComponent1.W = uvComponent1.W * float.Parse(materialValues[10], CultureInfo.InvariantCulture.NumberFormat);
                                }
                                if (uvMapComponents.Count() > 1)
                                {
                                    VertexFloat4Value uvTopComponent = (VertexFloat4Value)uvMapComponents.ElementAt(1);
                                    uvTopComponent.X = float.Parse(materialValues[13], CultureInfo.InvariantCulture.NumberFormat);
                                    uvTopComponent.Y = float.Parse(materialValues[13], CultureInfo.InvariantCulture.NumberFormat);
                                    uvTopComponent.Z = 1;
                                    uvTopComponent.W = 1;
                                }
                            }

                            //Apply transformation

                            //node.ItemsElementName.Where(g => g == Collada141.ItemsChoiceType2.rotate);


                            if (node.Items != null)
                            {
                                for (int transIndex = node.Items.Length - 1; transIndex >= 0; transIndex--)
                                {
                                    v = ApplyTransformation(v, node.Items[transIndex], node.ItemsElementName[transIndex]);
                                }
                            }

                            vertexList.Add(v);
                        }
                        elementIndex++;
                    }
                }
            }

            mesh.vertices.vertices         = new SporeMaster.RenderWare4.VertexBuffer(vertexList.Count);
            mesh.vertices.vertices.section = new RW4Section()
            {
                Number = verticesSectionNumber
            };
            mesh.vertices.vertexSize = vertexFormatSection.VertexSize;

            for (int i = 0; i < vertexList.Count; i++)
            {
                mesh.vertices.vertices[i] = vertexList[i];
            }

            //mesh.triangles = new RW4TriangleArray();
            mesh.triangles.triangles         = new Buffer <Triangle>(triangleDefinitions.Count / 3);
            mesh.triangles.triangles.section = new RW4Section()
            {
                Number = trianglesSectionNumber
            };


            for (int i = 0; i < triangleDefinitions.Count / 3; i++)
            {
                mesh.triangles.triangles[i] = new Triangle()
                {
                    i = (uint)triangleDefinitions[(i * 3)],
                    j = (uint)triangleDefinitions[(i * 3) + 1],
                    k = (uint)triangleDefinitions[(i * 3) + 2],
                };
            }


            return(mesh);
        }
示例#11
0
        private void SaveRW4Model()
        {
            //Save the new thing to a stream!

            if (this.DataContext != null)
            {
                //  try
                //  {

                ModifiedRW4File   modifiedData = new ModifiedRW4File();
                DatabaseIndexData index        = (DatabaseIndexData)this.DataContext;

                using (Stream stream = new MemoryStream(index.Data))
                {
                    //first read the current RW4model

                    List <RW4Section> sections = dataGrid1.ItemsSource as List <RW4Section>;
                    _rw4model.Sections = sections;

                    foreach (RW4Section section in _rw4model.Sections)
                    {
                        if (section.TypeCode == SectionTypeCodes.Texture)
                        {
                            SporeMaster.RenderWare4.Texture tex = section.obj as SporeMaster.RenderWare4.Texture;
                            _rw4model.Sections[(int)tex.texData.section.Number].obj = tex.texData;
                        }
                    }

                    RW4Section meshSection = _rw4model.Sections.Find(s => s.TypeCode == SectionTypeCodes.Mesh);
                    if (meshSection != null)
                    {
                        SporeMaster.RenderWare4.RW4Mesh mesh = meshSection.obj as SporeMaster.RenderWare4.RW4Mesh;

                        //update the bounding box

                        /*RW4Section bboxSection = _rw4model.Sections.Find(s => s.TypeCode == SectionTypeCodes.BBox);
                         * if (bboxSection != null)
                         * {
                         *  RW4BBox boundingBox = bboxSection.obj as RW4BBox;
                         *  if (meshSection != null)
                         *  {
                         *      boundingBox.minx = mesh.vertices.vertices.Min(v => v.X);
                         *      boundingBox.miny = mesh.vertices.vertices.Min(v => v.Y);
                         *      boundingBox.minz = mesh.vertices.vertices.Min(v => v.Z);
                         *
                         *      boundingBox.maxx = mesh.vertices.vertices.Max(v => v.X);
                         *      boundingBox.maxy = mesh.vertices.vertices.Max(v => v.Y);
                         *      boundingBox.maxz = mesh.vertices.vertices.Max(v => v.Z);
                         *
                         *      bboxSection.obj = boundingBox;
                         *  }
                         * }*/

                        _rw4model.Sections[(int)mesh.vertices.section.Number].obj  = mesh.vertices;
                        _rw4model.Sections[(int)mesh.triangles.section.Number].obj = mesh.triangles;

                        _rw4model.Sections[(int)mesh.vertices.vertices.section.Number].obj   = mesh.vertices.vertices.section.obj;
                        _rw4model.Sections[(int)mesh.triangles.triangles.section.Number].obj = mesh.triangles.triangles.section.obj;
                    }



                    //save back the model

                    using (MemoryStream writer = new MemoryStream())
                    {
                        _rw4model.Write(writer);

                        modifiedData.RW4FileData = writer.ToArray();
                        index.Index.ModifiedData = modifiedData;
                        index.Index.IsModified   = true;
                        index.Index.Compressed   = false;
                    }
                }

                //ViewHexDiff hex = new ViewHexDiff(index.Data, modifiedData.RW4FileData);
                //hex.ShowDialog();
            }
        }