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); }
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); }