Esempio n. 1
0
        private static IGeometry ConvertCollisionGeometry(Assimp.Node curAiNode, Assimp.Matrix4x4 nodeWorldTransform,
                                                          List <Assimp.Mesh> aiMeshes,
                                                          List <MaterialBuildInfo> materialBuildInfos)
        {
            var vertices  = new List <Assimp.Vector3D>();
            var triangles = new List <Basic.Triangle>();

            foreach (var aiMeshIndex in curAiNode.MeshIndices)
            {
                var aiMesh = aiMeshes[aiMeshIndex];

                for (var i = 0; i < aiMesh.Faces.Count; i++)
                {
                    var aiFace   = aiMesh.Faces[i];
                    var triangle = new Basic.Triangle();
                    var flip     = false;

                    if (!flip)
                    {
                        triangle.A = ( ushort )vertices.AddUnique(aiMesh.Vertices[aiFace.Indices[0]]);
                        triangle.B = aiFace.IndexCount > 1 ? ( ushort )vertices.AddUnique(aiMesh.Vertices[aiFace.Indices[1]]) : triangle.A;
                        triangle.C = aiFace.IndexCount > 2 ? ( ushort )vertices.AddUnique(aiMesh.Vertices[aiFace.Indices[2]]) : triangle.B;
                    }
                    else
                    {
                        triangle.C = ( ushort )vertices.AddUnique(aiMesh.Vertices[aiFace.Indices[0]]);
                        triangle.B = aiFace.IndexCount > 1 ? ( ushort )vertices.AddUnique(aiMesh.Vertices[aiFace.Indices[1]]) : triangle.A;
                        triangle.A = aiFace.IndexCount > 2 ? ( ushort )vertices.AddUnique(aiMesh.Vertices[aiFace.Indices[2]]) : triangle.B;
                    }

                    triangles.Add(triangle);
                }
            }

            var geometry = new Basic.Geometry
            {
                Meshes = new[]
                {
                    new Basic.Mesh
                    {
                        PrimitiveType = PrimitiveType.Triangles,
                        Primitives    = triangles.Cast <Basic.IPrimitive>().ToArray(),
                    }
                },
                VertexPositions = vertices.Select(x =>
                {
                    Assimp.Unmanaged.AssimpLibrary.Instance.TransformVecByMatrix4(ref x, ref nodeWorldTransform);
                    return(AssimpHelper.FromAssimp(x));
                }
                                                  ).ToArray()
            };

            geometry.Bounds = BoundingSphere.Calculate(geometry.VertexPositions);

            return(geometry);
        }
Esempio n. 2
0
        private static GC.Geometry ConvertBasicToGCGeometry(Basic.Geometry basicGeometry)
        {
            var geometry = new GC.Geometry();

            geometry.VertexBuffers.Add(new GC.VertexPositionBuffer(basicGeometry.VertexPositions));

            var positionFlags = GC.IndexAttributeFlags.HasPosition;

            if (basicGeometry.VertexCount > byte.MaxValue)
            {
                positionFlags |= GC.IndexAttributeFlags.Position16BitIndex;
            }

            var indexFlagsParams = new List <GC.IndexAttributeFlagsParam>();
            var normals          = new List <Vector3>();
            var uvs    = new List <Vector2 <short> >();
            var colors = new List <Color>();

            foreach (var basicMesh in basicGeometry.Meshes)
            {
                var basicMaterial = basicGeometry.Materials[basicMesh.MaterialId];
                var mesh          = new GC.Mesh();

                var indexFlags       = positionFlags;
                var useColors        = false;
                var hasColors        = basicMesh.Colors != null;
                var hasUVs           = basicMesh.UVs != null;
                var hasVertexNormals = basicGeometry.VertexNormals != null;
                var hasNormals       = hasVertexNormals || basicMesh.Normals != null;

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

                if (hasUVs)
                {
                    indexFlags |= GC.IndexAttributeFlags.HasUV;
                }

                //Debug.Assert( indexFlags == ( GC.IndexAttributeFlags.HasPosition | GC.IndexAttributeFlags.HasNormal ) ||
                //              indexFlags == ( GC.IndexAttributeFlags.Position16BitIndex | GC.IndexAttributeFlags.HasPosition | GC.IndexAttributeFlags.Normal16BitIndex | GC.IndexAttributeFlags.HasNormal ) ||
                //              indexFlags == ( GC.IndexAttributeFlags.HasPosition | GC.IndexAttributeFlags.HasColor ) ||
                //              indexFlags == ( GC.IndexAttributeFlags.Position16BitIndex | GC.IndexAttributeFlags.HasPosition | GC.IndexAttributeFlags.Color16BitIndex | GC.IndexAttributeFlags.HasColor ) ||
                //              indexFlags == ( GC.IndexAttributeFlags.HasPosition | GC.IndexAttributeFlags.HasNormal | GC.IndexAttributeFlags.HasUV ) ||
                //              indexFlags == ( GC.IndexAttributeFlags.Position16BitIndex | GC.IndexAttributeFlags.HasPosition | GC.IndexAttributeFlags.Normal16BitIndex | GC.IndexAttributeFlags.HasNormal | GC.IndexAttributeFlags.HasUV ) ||
                //              indexFlags == ( GC.IndexAttributeFlags.HasPosition | GC.IndexAttributeFlags.HasColor | GC.IndexAttributeFlags.HasUV ) ||
                //              indexFlags == ( GC.IndexAttributeFlags.Position16BitIndex | GC.IndexAttributeFlags.HasPosition | GC.IndexAttributeFlags.Color16BitIndex | GC.IndexAttributeFlags.HasColor | GC.IndexAttributeFlags.HasUV ) ||
                //              indexFlags == ( GC.IndexAttributeFlags.HasPosition | GC.IndexAttributeFlags.HasNormal | GC.IndexAttributeFlags.UV16BitIndex | GC.IndexAttributeFlags.HasUV ) ||
                //              indexFlags == ( GC.IndexAttributeFlags.Position16BitIndex | GC.IndexAttributeFlags.HasPosition | GC.IndexAttributeFlags.Normal16BitIndex | GC.IndexAttributeFlags.HasNormal | GC.IndexAttributeFlags.UV16BitIndex | GC.IndexAttributeFlags.HasUV ) ||
                //              indexFlags == ( GC.IndexAttributeFlags.HasPosition | GC.IndexAttributeFlags.HasColor | GC.IndexAttributeFlags.UV16BitIndex | GC.IndexAttributeFlags.HasUV ) ||
                //              indexFlags == ( GC.IndexAttributeFlags.Position16BitIndex | GC.IndexAttributeFlags.HasPosition | GC.IndexAttributeFlags.Color16BitIndex | GC.IndexAttributeFlags.HasColor | GC.IndexAttributeFlags.UV16BitIndex | GC.IndexAttributeFlags.HasUV ) );

                // Set up parameters
                var indexFlagsParam = new GC.IndexAttributeFlagsParam(indexFlags);
                mesh.Parameters.Add(indexFlagsParam);
                indexFlagsParams.Add(indexFlagsParam);

                if (useColors)
                {
                    mesh.Parameters.Add(new GC.LightingParams(GC.LightingParams.Preset.Colors));
                }
                else
                {
                    mesh.Parameters.Add(new GC.LightingParams(GC.LightingParams.Preset.Normals));
                }

                mesh.Parameters.Add(new GC.TextureParams(( ushort )(basicMaterial.TextureId)));
                mesh.Parameters.Add(new GC.MipMapParams());

                // Build display list
                var basicTriangles = basicMesh.ToTriangles();
                for (int i = 0; i < basicTriangles.Length; i += 3)
                {
                    var temp = basicTriangles[i];
                    basicTriangles[i]     = basicTriangles[i + 2];
                    basicTriangles[i + 2] = temp;
                }

                var displayListIndices = new GC.Index[basicTriangles.Length];
                for (int i = 0; i < basicTriangles.Length; i++)
                {
                    var index      = new GC.Index();
                    var basicIndex = basicTriangles[i];
                    index.PositionIndex = basicIndex.VertexIndex;

                    if (useColors)
                    {
                        var color      = hasColors ? basicIndex.Color : Color.White;
                        var colorIndex = colors.IndexOf(color);
                        if (colorIndex == -1)
                        {
                            colorIndex = colors.Count;
                            colors.Add(color);
                        }

                        index.ColorIndex = ( ushort )colorIndex;
                    }
                    else
                    {
                        var normal      = hasVertexNormals ? basicGeometry.VertexNormals[basicIndex.VertexIndex] : basicIndex.Normal;
                        var normalIndex = normals.IndexOf(normal);
                        if (normalIndex == -1)
                        {
                            normalIndex = normals.Count;
                            normals.Add(normal);
                        }

                        index.NormalIndex = ( ushort )normalIndex;
                    }

                    if (hasUVs)
                    {
                        var uv      = basicIndex.UV;
                        var uvIndex = uvs.IndexOf(uv);
                        if (uvIndex == -1)
                        {
                            uvIndex = uvs.Count;
                            uvs.Add(uv);
                        }

                        index.UVIndex = ( ushort )uvIndex;
                    }

                    displayListIndices[i] = index;
                }

                var displayList = new GC.GXDisplayList(GC.GXPrimitive.Triangles, displayListIndices);
                mesh.DisplayLists.Add(displayList);
                geometry.OpaqueMeshes.Add(mesh);
            }

            if (normals.Count > 0)
            {
                if (normals.Count > byte.MaxValue)
                {
                    foreach (var param in indexFlagsParams)
                    {
                        if (param.Flags.HasFlag(GC.IndexAttributeFlags.HasNormal))
                        {
                            param.Flags |= GC.IndexAttributeFlags.Normal16BitIndex;
                        }
                    }
                }

                geometry.VertexBuffers.Add(new GC.VertexNormalBuffer(normals.ToArray()));
            }

            if (colors.Count > 0)
            {
                if (colors.Count > byte.MaxValue)
                {
                    foreach (var param in indexFlagsParams)
                    {
                        if (param.Flags.HasFlag(GC.IndexAttributeFlags.HasColor))
                        {
                            param.Flags |= GC.IndexAttributeFlags.Color16BitIndex;
                        }
                    }
                }

                geometry.VertexBuffers.Add(new GC.VertexColorBuffer(colors.ToArray()));
            }

            if (uvs.Count > 0)
            {
                if (uvs.Count > byte.MaxValue)
                {
                    foreach (var param in indexFlagsParams)
                    {
                        if (param.Flags.HasFlag(GC.IndexAttributeFlags.HasUV))
                        {
                            param.Flags |= GC.IndexAttributeFlags.UV16BitIndex;
                        }
                    }
                }

                geometry.VertexBuffers.Add(new GC.VertexUVBuffer(uvs.ToArray()));
            }

            geometry.Bounds = basicGeometry.Bounds;
            return(geometry);
        }