Exemple #1
0
        private static IGeometry ConvertDisplayGeometry(Assimp.Node curAiNode, Assimp.Matrix4x4 nodeWorldTransform, List <Assimp.Mesh> aiMeshes, List <MaterialBuildInfo> materialBuildInfos)
        {
            var nodeInverseWorldTransform = nodeWorldTransform;

            nodeInverseWorldTransform.Inverse();
            var nodeInverseTransposeWorldTransform = nodeInverseWorldTransform;

            nodeInverseTransposeWorldTransform.Transpose();

            var geometry = new Geometry();

            // Convert meshes
            var vertexPositions = new List <Assimp.Vector3D>();
            var vertexNormals   = new List <Assimp.Vector3D>();
            var vertexUVs       = new List <Assimp.Vector3D>();
            var vertexColors    = new List <Assimp.Color4D>();
            var lastRenderState = new MeshRenderState();

            foreach (var aiMeshIndex in curAiNode.MeshIndices)
            {
                var aiMesh      = aiMeshes[aiMeshIndex];
                var material    = materialBuildInfos[aiMesh.MaterialIndex];
                var mesh        = new Mesh();
                var renderState = new MeshRenderState();

                renderState.IndexFlags = IndexAttributeFlags.HasPosition;
                var useColors  = false;
                var hasColors  = aiMesh.HasVertexColors(0);
                var hasUVs     = aiMesh.HasTextureCoords(0);
                var hasNormals = aiMesh.HasNormals;

                if (hasColors || !hasNormals)
                {
                    renderState.IndexFlags |= IndexAttributeFlags.HasColor;
                    useColors = true;
                }
                else
                {
                    renderState.IndexFlags |= IndexAttributeFlags.HasNormal;
                }

                if (hasUVs)
                {
                    renderState.IndexFlags |= IndexAttributeFlags.HasUV;
                }

                // Convert faces
                var triangleIndices = new Index[aiMesh.FaceCount * 3];
                for (var i = 0; i < aiMesh.Faces.Count; i++)
                {
                    var aiFace = aiMesh.Faces[i];

                    for (var j = 0; j < 3; j++)
                    {
                        var triangleIndicesIndex = (i * 3) + 2 - j;

                        if (j >= aiFace.IndexCount)
                        {
                            triangleIndices[triangleIndicesIndex] = triangleIndices[triangleIndicesIndex + 1];
                            continue;
                        }

                        int aiFaceIndex = aiFace.Indices[j];

                        var position      = aiMesh.Vertices[aiFaceIndex];
                        var positionIndex = vertexPositions.AddUnique(position);
                        if (positionIndex > byte.MaxValue)
                        {
                            renderState.IndexFlags |= IndexAttributeFlags.Position16BitIndex;
                        }

                        var normalIndex = 0;
                        var colorIndex  = 0;
                        var uvIndex     = 0;

                        if (useColors)
                        {
                            var color = hasColors ? aiMesh.VertexColorChannels[0][aiFaceIndex] : new Assimp.Color4D();
                            colorIndex = vertexColors.AddUnique(color);

                            if (colorIndex > byte.MaxValue)
                            {
                                renderState.IndexFlags |= IndexAttributeFlags.Color16BitIndex;
                            }
                        }
                        else
                        {
                            var normal = aiMesh.Normals[aiFaceIndex];
                            normalIndex = vertexNormals.AddUnique(normal);

                            if (normalIndex > byte.MaxValue)
                            {
                                renderState.IndexFlags |= IndexAttributeFlags.Normal16BitIndex;
                            }
                        }

                        if (hasUVs)
                        {
                            var uv = aiMesh.TextureCoordinateChannels[0][aiFaceIndex];
                            uvIndex = vertexUVs.AddUnique(uv);

                            if (uvIndex > byte.MaxValue)
                            {
                                renderState.IndexFlags |= IndexAttributeFlags.UV16BitIndex;
                            }
                        }

                        triangleIndices[triangleIndicesIndex] = new Index
                        {
                            PositionIndex = ( ushort )positionIndex,
                            NormalIndex   = ( ushort )normalIndex,
                            ColorIndex    = ( ushort )colorIndex,
                            UVIndex       = ( ushort )uvIndex
                        };
                    }
                }

                // Build display list
                var displayList = new GXDisplayList(GXPrimitive.Triangles, triangleIndices);
                mesh.DisplayLists.Add(displayList);

                // Set up render params
                if (renderState.IndexFlags != lastRenderState.IndexFlags)
                {
                    mesh.Parameters.Add(new IndexAttributeFlagsParam(renderState.IndexFlags));
                }

                // Set up render lighting params
                {
                    if (useColors)
                    {
                        renderState.LightingValue1 = 0x0b11;
                    }
                    else
                    {
                        renderState.LightingValue2 = 0x0011;
                    }

                    renderState.LightingValue2 = 1;

                    if (renderState.LightingValue1 != lastRenderState.LightingValue1 ||
                        renderState.LightingValue2 != lastRenderState.LightingValue2)
                    {
                        mesh.Parameters.Add(new LightingParams()
                        {
                            Value1 = renderState.LightingValue1,
                            Value2 = renderState.LightingValue2
                        });
                    }
                }

                // Set up render texture params
                {
                    renderState.TextureId = ( ushort )material.TextureId;
                    renderState.TileMode  = TileMode.WrapU | TileMode.WrapV;

                    if (renderState.TextureId != lastRenderState.TextureId ||
                        renderState.TileMode != lastRenderState.TileMode)
                    {
                        mesh.Parameters.Add(new TextureParams(renderState.TextureId, renderState.TileMode));
                    }
                }

                // Set up render mipmap params
                {
                    renderState.MipMapValue1 = 0x104a;
                    renderState.MipMapValue2 = 0;

                    if (renderState.MipMapValue1 != lastRenderState.MipMapValue1 ||
                        renderState.MipMapValue2 != lastRenderState.MipMapValue2)
                    {
                        mesh.Parameters.Add(new MipMapParams {
                            Value1 = renderState.MipMapValue1, Value2 = renderState.MipMapValue2
                        });
                    }
                }

                //if ( material.UseAlpha )
                //{
                //    mesh.Parameters.Add( new BlendAlphaParam() { Flags = BlendAlphaFlags.UseAlpha } );
                //    geometry.TranslucentMeshes.Add( mesh );
                //}
                //else
                //{
                //    geometry.OpaqueMeshes.Add( mesh );
                //}

                geometry.OpaqueMeshes.Add(mesh);
                lastRenderState = renderState;
            }

            // Build vertex buffers
            if (vertexPositions.Count > 0)
            {
                Debug.Assert(vertexPositions.Count <= ushort.MaxValue);
                var localVertexPositions = vertexPositions.Select(x =>
                {
                    Assimp.Unmanaged.AssimpLibrary.Instance.TransformVecByMatrix4(ref x, ref nodeWorldTransform);
                    return(AssimpHelper.FromAssimp(x));
                }).ToArray();
                geometry.VertexBuffers.Add(new VertexPositionBuffer(localVertexPositions));
                geometry.Bounds = BoundingSphere.Calculate(localVertexPositions);
            }

            if (vertexNormals.Count > 0)
            {
                Debug.Assert(vertexNormals.Count <= ushort.MaxValue);
                geometry.VertexBuffers.Add(new VertexNormalBuffer(vertexNormals.Select(x =>
                {
                    Assimp.Unmanaged.AssimpLibrary.Instance.TransformVecByMatrix4(ref x, ref nodeInverseTransposeWorldTransform);
                    return(AssimpHelper.FromAssimp(x));
                }).ToArray()));
            }

            if (vertexColors.Count > 0)
            {
                Debug.Assert(vertexColors.Count <= ushort.MaxValue);
                geometry.VertexBuffers.Add(new VertexColorBuffer(vertexColors.Select(AssimpHelper.FromAssimp).ToArray()));
            }

            if (vertexUVs.Count > 0)
            {
                Debug.Assert(vertexUVs.Count <= ushort.MaxValue);
                geometry.VertexBuffers.Add(new VertexUVBuffer(vertexUVs.Select(x =>
                                                                               UVCodec.Encode255(AssimpHelper
                                                                                                 .FromAssimpAsVector2(x)))
                                                              .ToArray()));
            }

            return(geometry);
        }
        private static void AddVertexContainer(GXVertexDecompressor decom, List <IndexedVertexData <MeleeVertex> > vertexContainers, DatPolygon polygon, GXDisplayList displayList)
        {
            List <MeleeVertex> vertices      = new List <MeleeVertex>();
            List <int>         vertexIndices = new List <int>();

            for (int i = 0; i < displayList.Indices.Length; i++)
            {
                vertexIndices.Add(i);
            }

            vertices.AddRange(ConvertVerts(decom.GetFormattedVertices(displayList, polygon)));

            PrimitiveType primitiveType   = MeleeDatToOpenGL.GetGLPrimitiveType(displayList.PrimitiveType);
            var           vertexContainer = new IndexedVertexData <MeleeVertex>(vertices, vertexIndices, primitiveType);

            vertexContainers.Add(vertexContainer);
        }
Exemple #3
0
        private void ParseDOBJs(IHSDNode node, HSD_JOBJ parent, List <HSD_JOBJ> BoneList)
        {
            if (node is HSD_JOBJ jobj)
            {
                if (jobj.DOBJ != null)
                {
                    foreach (var child in jobj.DOBJ.List)
                    {
                        ParseDOBJs(child, jobj, BoneList);
                    }
                }
                foreach (var child in jobj.Children)
                {
                    ParseDOBJs(child, child, BoneList);
                }
            }
            if (node is HSD_DOBJ dobj)
            {
                Console.WriteLine("DOBJ found");
                GenericMesh mesh = new GenericMesh();
                mesh.Name = "Mesh_" + outModel.Meshes.Count;

                GenericMaterial mat = new GenericMaterial();
                mesh.MaterialName = "material_" + outModel.MaterialBank.Count;
                outModel.MaterialBank.Add(mesh.MaterialName, mat);

                var Xscale = 1;
                var Yscale = 1;

                if (dobj.MOBJ != null)
                {
                    if (dobj.MOBJ.Textures != null)
                    {
                        var tobj = dobj.MOBJ.Textures;

                        mat.SWrap = GXTranslator.toWrapMode(tobj.WrapS);
                        mat.TWrap = GXTranslator.toWrapMode(tobj.WrapT);

                        Xscale = tobj.WScale;
                        Yscale = tobj.HScale;

                        if (!tobjToIndex.ContainsKey(tobj.ImageData.Data))
                        {
                            Bitmap B = null;
                            if (tobj.ImageData != null)
                            {
                                if (tobj.Tlut != null)
                                {
                                    B = TPL.ConvertFromTextureMelee(tobj.ImageData.Data, tobj.ImageData.Width, tobj.ImageData.Height, (int)tobj.ImageData.Format, tobj.Tlut.Data, tobj.Tlut.ColorCount, (int)tobj.Tlut.Format);
                                }
                                else
                                {
                                    B = TPL.ConvertFromTextureMelee(tobj.ImageData.Data, tobj.ImageData.Width, tobj.ImageData.Height, (int)tobj.ImageData.Format, null, 0, 0);
                                }
                            }
                            GenericTexture t = new GenericTexture();
                            t.FromBitmap(B);
                            B.Dispose();

                            tobjToIndex.Add(tobj.ImageData.Data, outModel.TextureBank.Count);
                            outModel.TextureBank.Add("texture_" + outModel.TextureBank.Count, t);
                        }

                        mat.TextureDiffuse = outModel.TextureBank.Keys.ToArray()[tobjToIndex[tobj.ImageData.Data]];
                    }
                }

                outModel.Meshes.Add(mesh);
                if (dobj.POBJ != null)
                {
                    foreach (HSD_POBJ pobj in dobj.POBJ.List)
                    {
                        // Decode the Display List Data
                        GXDisplayList DisplayList  = new GXDisplayList(pobj.DisplayListBuffer, pobj.VertexAttributes);
                        var           Vertices     = ToGenericVertex(VertexAccessor.GetDecodedVertices(pobj), BoneList, pobj.BindGroups != null ? new List <HSD_JOBJWeight>(pobj.BindGroups.Elements) : null, parent);
                        int           bufferOffset = 0;
                        foreach (GXPrimitiveGroup g in DisplayList.Primitives)
                        {
                            var primitiveType = GXTranslator.toPrimitiveType(g.PrimitiveType);

                            var strip = new List <GenericVertex>();
                            for (int i = bufferOffset; i < bufferOffset + g.Count; i++)
                            {
                                strip.Add(Vertices[i]);
                            }
                            bufferOffset += g.Count;

                            switch (primitiveType)
                            {
                            case OpenTK.Graphics.OpenGL.PrimitiveType.TriangleStrip:
                                Tools.TriangleConverter.StripToList(strip, out strip);
                                break;

                            case OpenTK.Graphics.OpenGL.PrimitiveType.Quads:
                                Tools.TriangleConverter.QuadToList(strip, out strip);
                                break;

                            case OpenTK.Graphics.OpenGL.PrimitiveType.Triangles:
                                break;

                            default:
                                Debug.WriteLine("Error converting primitive type " + primitiveType);
                                break;
                            }

                            mesh.Vertices.AddRange(strip);
                        }
                    }
                }

                for (int i = 0; i < mesh.Vertices.Count; i++)
                {
                    var vert = mesh.Vertices[i];
                    vert.UV0         = new Vector2(vert.UV0.X * Xscale, vert.UV0.Y * Yscale);
                    mesh.Vertices[i] = vert;
                }
                mesh.Optimize();
                Tools.TriangleConverter.ReverseFaces(mesh.Triangles, out mesh.Triangles);
            }
        }