예제 #1
0
        public Node Import(string path, string texturePakPath = null)
        {
            // Import scene.
            var aiScene            = AssimpHelper.ImportScene(path, false);
            var materialBuildInfos = BuildProceduralMaterials(Path.GetDirectoryName(path), aiScene.Materials, texturePakPath);
            var rootNode           = ConvertNode(aiScene.RootNode, aiScene.Meshes, materialBuildInfos);

            return(rootNode);
        }
예제 #2
0
        public LandTableSA2 Import(string path, string texturePakPath = null)
        {
            var landTable = new LandTableSA2();
            var aiScene   = AssimpHelper.ImportScene(path, false);
            var meshNodes = FindMeshNodes(aiScene.RootNode);

            // Convert textures & build materials
            var convertMaterialsAndTextures = ConvertMaterialsAndTextures(Path.GetDirectoryName(path), aiScene.Materials, texturePakPath);

            landTable.TexturePakFileName = Path.GetFileNameWithoutExtension(texturePakPath);
            landTable.Textures           = convertMaterialsAndTextures.TextureReferences;

            var displayModels   = new List <LandModelSA2>();
            var collisionModels = new List <LandModelSA2>();

            foreach (var aiMeshNode in meshNodes)
            {
                if (!aiMeshNode.Name.Contains("hkRB"))
                {
                    displayModels.Add(ConvertDisplayModel(aiScene, convertMaterialsAndTextures.MaterialBuildInfos, aiMeshNode));
                }
                else
                {
                    collisionModels.Add(ConvertCollisionModel(aiScene, convertMaterialsAndTextures.MaterialBuildInfos, aiMeshNode));
                    displayModels.Add(ConvertDisplayModel(aiScene, convertMaterialsAndTextures.MaterialBuildInfos, aiMeshNode));
                    //var collisionModel = new LandModelSA2();
                    //collisionModel.Flags |= SurfaceFlags.Collidable;
                    //collisionModel.RootNode = ConvertNode( aiMeshNode, aiScene.Meshes, convertMaterialsAndTextures.MaterialBuildInfos,
                    //                                       ConvertCollisionGeometry );

                    //var collisionGeometry = ( Basic.Geometry )collisionModel.RootNode.Geometry;
                    //collisionModel.Bounds = collisionGeometry.Bounds;

                    //collisionModels.Add( collisionModel );
                }
            }

            landTable.Models.AddRange(displayModels);
            landTable.Models.AddRange(collisionModels);

            return(landTable);
        }
        public override Motion Import(string filepath, Config config)
        {
            var aiScene     = AssimpHelper.ImportScene(filepath);
            var aiAnimation = aiScene.Animations.FirstOrDefault();

            if (aiAnimation == null)
            {
                return(null);
            }

            var motion = new Motion {
                Duration = ConvertTime(aiAnimation.DurationInTicks, aiAnimation.TicksPerSecond)
            };

            foreach (var aiChannel in aiAnimation.NodeAnimationChannels)
            {
                var nodeName  = aiChannel.NodeName;
                var nodeIndex = ( short )(config.NodeIndexResolver?.Invoke(nodeName) ?? FindNodeIndex(aiScene.RootNode, nodeName));
                Debug.Assert(nodeIndex != -1);

                if (aiChannel.HasPositionKeys)
                {
                    var controller = new NodeController(ControllerType.Position, nodeIndex, aiChannel.NodeName);
                    foreach (var aiKey in aiChannel.PositionKeys)
                    {
                        controller.Keys.Add(new Vector3Key
                        {
                            Time  = ConvertTime(aiKey.Time, aiAnimation.TicksPerSecond),
                            Value = aiKey.Value.FromAssimp()
                        });
                    }

                    motion.Controllers.Add(controller);
                }

                if (aiChannel.HasRotationKeys)
                {
                    var controller = new NodeController(ControllerType.Rotation, nodeIndex, aiChannel.NodeName);
                    foreach (var aiKey in aiChannel.RotationKeys)
                    {
                        controller.Keys.Add(new QuaternionKey
                        {
                            Time  = ConvertTime(aiKey.Time, aiAnimation.TicksPerSecond),
                            Value = Quaternion.Inverse(aiKey.Value.FromAssimp())
                        });
                    }

                    motion.Controllers.Add(controller);
                }

                if (aiChannel.HasScalingKeys)
                {
                    var controller = new NodeController(ControllerType.Scale, nodeIndex, aiChannel.NodeName);
                    foreach (var aiKey in aiChannel.ScalingKeys)
                    {
                        controller.Keys.Add(new Vector3Key
                        {
                            Time  = ConvertTime(aiKey.Time, aiAnimation.TicksPerSecond),
                            Value = aiKey.Value.FromAssimp()
                        });
                    }

                    motion.Controllers.Add(controller);
                }
            }

            return(motion);
        }
예제 #4
0
        public Node Import(string path, string texturePakPath = null)
        {
            // Import scene.
            var aiScene = AssimpHelper.ImportScene(path, true);

            // Find the node root of the animated hierarchy. This assumes that only 1 hierarchy exists, and any other
            // nodes that part of the scene root are mesh nodes.
            var aiRootNode = FindHierarchyRootNode(aiScene.RootNode);

            // Convert the nodes in the animated hierarchy from Assimps format, and also keep track of additional info.
            var convertedNodes = ConvertNodes(aiRootNode);

            // Find the mesh nodes within the scene. A mesh node is a node with 1 or more meshes attached to it.
            var meshNodes = FindMeshNodes(aiScene.RootNode);

            // Map each mesh node to a target node in the animated hierarchy. This is because we can't add extra nodes
            // to the hierarchy, so we must determine the most appropriate node to add the mesh to.
            var mappedMeshes = MapMeshNodesToTargetNodes(meshNodes, aiScene.Meshes, convertedNodes);

            // Convert the materials and textures
            var materialBuildInfos =
                BuildProceduralMaterials(Path.GetDirectoryName(path), aiScene.Materials, texturePakPath);

            // Take the mapped meshes and merge them into 1 geometry per target node
            // Also builds any supplementary geometries have have to be added to store additional weighted vertex info
            var geometryBuildInfos = BuildProceduralGeometries(mappedMeshes, convertedNodes, materialBuildInfos);

            var weightedVertexIdLookup = new Dictionary <Vertex, int>();
            var nextWeightedVertexId   = 4095;

            foreach (var geometryBuildInfo in geometryBuildInfos)
            {
                // Get target node inverse world transform to transform the vertices the target node's local space
                Matrix4x4.Invert(geometryBuildInfo.TargetNodeInfo.Node.WorldTransform, out var targetNodeInvWorldTransform);

                // Start building geometry
                var geometry = new Geometry();

                if (!geometryBuildInfo.IsSupplementary && geometryBuildInfo.UnweightedVertices.Count > 0)
                {
                    // Add unweighted vertices
                    geometry.VertexList.Add(new VertexNChunk(geometryBuildInfo.UnweightedVertices.Select(x => new VertexN
                    {
                        Position = Vector3.Transform(x.Position, targetNodeInvWorldTransform),
                        Normal   = Vector3.TransformNormal(x.Normal, targetNodeInvWorldTransform)
                    }).ToArray())
                    {
                        BaseIndex = geometryBuildInfo.UnweightedVertices[0].Id
                    });
                }

                if (!sDisableWeights)
                {
                    BuildWeightedVertexChunks(geometry, geometryBuildInfo, ref targetNodeInvWorldTransform, weightedVertexIdLookup, ref nextWeightedVertexId);
                }

                if (!geometryBuildInfo.IsSupplementary)
                {
                    BuildPolygonList(geometry, geometryBuildInfo, weightedVertexIdLookup);
                }

                geometryBuildInfo.TargetNodeInfo.Node.Geometry = geometry;
            }

            foreach (var nodeInfo in convertedNodes)
            {
                nodeInfo.Node.OptimizeFlags();
            }

            var rootNode = convertedNodes[0];

            return(rootNode.Node);
        }
예제 #5
0
        public static Model Import(string filepath, bool conformanceMode = true)
        {
            var      model    = new Model();
            Geometry geometry = null;

            if (conformanceMode)
            {
                geometry = new Geometry {
                    Name = "polySurfaceShape6"
                };
                model.Geometries.Add(geometry);
            }

            var aiScene = AssimpHelper.ImportScene(filepath, false);

            void ConvertNode(Assimp.Node aiNode)
            {
                if (aiNode.HasMeshes)
                {
                    var nodeWorldTransform = AssimpHelper.CalculateWorldTransform(aiNode);

                    if (!conformanceMode)
                    {
                        geometry = new Geometry {
                            Name = aiNode.Name
                        }
                    }
                    ;

                    foreach (var aiMeshIndex in aiNode.MeshIndices)
                    {
                        var aiMesh     = aiScene.Meshes[aiMeshIndex];
                        var aiMaterial = aiScene.Materials[aiMesh.MaterialIndex];

                        var mesh = new Mesh();

                        mesh.Material.Name = aiMaterial.Name;
                        //mesh.Material.Ambient = new Vector4( aiMaterial.ColorAmbient.R, aiMaterial.ColorAmbient.G, aiMaterial.ColorAmbient.B, aiMaterial.ColorAmbient.A );
                        //mesh.Material.Diffuse = new Vector4( aiMaterial.ColorDiffuse.R, aiMaterial.ColorDiffuse.G, aiMaterial.ColorDiffuse.B,aiMaterial.ColorDiffuse.A );
                        //mesh.Material.Specular = new Vector4( aiMaterial.ColorSpecular.R, aiMaterial.ColorSpecular.G, aiMaterial.ColorSpecular.B, aiMaterial.ColorSpecular.A );
                        mesh.Material.TextureName =
                            Path.ChangeExtension(Path.GetFileNameWithoutExtension(aiMaterial.TextureDiffuse.FilePath), "dds");

                        mesh.Vertices = new Vertex[aiMesh.VertexCount];
                        for (int i = 0; i < mesh.Vertices.Length; i++)
                        {
                            ref var vertex = ref mesh.Vertices[i];
                            vertex.Position = Vector3.Transform(AssimpHelper.FromAssimp(aiMesh.Vertices[i]), nodeWorldTransform);
                            vertex.Normal   = aiMesh.HasNormals ? Vector3.TransformNormal(AssimpHelper.FromAssimp(aiMesh.Normals[i]), nodeWorldTransform) : new Vector3();
                            vertex.Color    = aiMesh.HasVertexColors(0)
                                ? AssimpHelper.FromAssimp(aiMesh.VertexColorChannels[0][i])
                                : Color.White;
                            vertex.UV = aiMesh.HasTextureCoords(0)
                                ? AssimpHelper.FromAssimpAsVector2(aiMesh.TextureCoordinateChannels[0][i])
                                : new Vector2();
                        }

                        mesh.Indices = aiMesh.GetIndices();
                        geometry.Meshes.Add(mesh);
                    }

                    if (!conformanceMode)
                    {
                        model.Geometries.Add(geometry);
                    }
                }

                foreach (var aiChildNode in aiNode.Children)
                {
                    ConvertNode(aiChildNode);
                }
            }

            ConvertNode(aiScene.RootNode);

            if (conformanceMode)
            {
                var meshes = new List <Mesh>(geometry.Meshes);

                var meshMap = new List <int>();
                var nextUniqueNewMeshIndex = sOriginalMaterialNames.Length;
                for (int i = 0; i < meshes.Count; i++)
                {
                    var newMeshIndex = Array.IndexOf(sOriginalMaterialNames, meshes[i].Material.Name);
                    if (newMeshIndex == -1)
                    {
                        newMeshIndex = nextUniqueNewMeshIndex++;
                    }

                    meshMap.Add(newMeshIndex);
                }

                geometry.Meshes.Clear();
                for (int i = 0; i < nextUniqueNewMeshIndex; i++)
                {
                    if (!meshMap.Contains(i))
                    {
                        geometry.Meshes.Add(new Mesh
                        {
                            Indices  = new int[0],
                            Vertices = new Vertex[0],
                            Material = new Material
                            {
                                Name        = sOriginalMaterialNames[i % sOriginalMaterialNames.Length],
                                TextureName = sOriginalTextureNames[i % sOriginalTextureNames.Length]
                            }
                        });
                    }
                    else
                    {
                        geometry.Meshes.Add(null);
                    }
                }

                for (int i = 0; i < meshMap.Count; i++)
                {
                    geometry.Meshes[meshMap[i]] = meshes[i];
                }
            }

            return(model);
        }