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