public virtual Assimp.Node assimpExport(ref Assimp.Scene scn, ref Dictionary <int, int> meshImportStatus) { //Default shit //Create assimp node Assimp.Node node = new Assimp.Node(Name); node.Transform = MathUtils.convertMatrix(localMat); //Handle animations maybe? int animComponentId = hasComponent(typeof(AnimComponent)); if (animComponentId > -1) { AnimComponent cmp = (AnimComponent)_components[animComponentId]; cmp.assimpExport(ref scn); } foreach (Model child in children) { Assimp.Node c = child.assimpExport(ref scn, ref meshImportStatus); node.Children.Add(c); } return(node); }
private LoadedModel LoadModelOfd() { OpenFileDialog ofd = new OpenFileDialog(); if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) { if (ofd.CheckFileExists) { string dirName = Path.GetDirectoryName(ofd.FileName); try { using (Assimp.AssimpContext importer = new Assimp.AssimpContext()) { importer.SetConfig(new NormalSmoothingAngleConfig(66.0f)); Assimp.Scene model = importer.ImportFile(ofd.FileName, Assimp.PostProcessPreset.TargetRealTimeMaximumQuality); LoadedModel loadedModel = new LoadedModel(model, dirName); loadedModel.Name = Path.GetFileName(ofd.FileName); return(loadedModel); } } catch { System.Windows.MessageBox.Show("Unsupported file type.", "Error"); } } } return(null); }
public void FillScene(Assimp.Scene scene, TEX1 textures, string fileDir) { textures.DumpTextures(fileDir); foreach (Material mat in m_Materials) { Assimp.Material assMat = new Assimp.Material(); if (mat.TextureIndices[0] != -1) { int texIndex = mat.TextureIndices[0]; //texIndex = m_TexRemapBlock[texIndex]; string texPath = Path.Combine(fileDir, textures[texIndex].Name + ".png"); Assimp.TextureSlot tex = new Assimp.TextureSlot(texPath, Assimp.TextureType.Diffuse, 0, Assimp.TextureMapping.FromUV, 0, 1.0f, Assimp.TextureOperation.Add, textures[texIndex].WrapS.ToAssImpWrapMode(), textures[texIndex].WrapT.ToAssImpWrapMode(), 0); assMat.AddMaterialTexture(ref tex); } if (mat.MaterialColors[0] != null) { assMat.ColorDiffuse = mat.MaterialColors[0].Value.ToColor4D(); } if (mat.AmbientColors[0] != null) { assMat.ColorAmbient = mat.AmbientColors[0].Value.ToColor4D(); } scene.Materials.Add(assMat); } }
private bool loadFile(string path) { Assimp.AssimpContext importer = new Assimp.AssimpContext(); importer.SetConfig(new NormalSmoothingAngleConfig(66f)); //TODO check which other post processes we need m_scene = importer.ImportFile(path, Assimp.PostProcessSteps.CalculateTangentSpace | Assimp.PostProcessSteps.GenerateNormals | Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.JoinIdenticalVertices | Assimp.PostProcessSteps.OptimizeMeshes); //failed loading :( if (!m_scene.HasMeshes) { textBoxInfo.Text = "No Valid Meshes found."; return(false); } //display some info string msg = "Mesh Count: " + m_scene.MeshCount.ToString() + Environment.NewLine + "Material count: " + m_scene.MaterialCount.ToString() + " (Maximum material count is 32)"; textBoxInfo.Text = msg; buttonSave.Enabled = (m_scene.MeshCount > 0 && m_scene.MaterialCount <= maxMaterials); return(true); }
public JointModel(Assimp.Scene scene, AllBoneInfos allBoneInfos) { this.scene = scene; this.allBoneInfos = allBoneInfos; this.positions = GetPositions(scene); this.transforms = GetTransforms(scene); this.boneIndexes = GetIndexes(scene, allBoneInfos); //this.inversedTransforms = new mat4[this.transforms.Length]; //for (int i = 0; i < this.transforms.Length; i++) //{ // this.inversedTransforms[i] = glm.inverse(this.transforms[i]); //} //AllBones allBones = container.GetAllBones(); //BoneInfo[] boneInfos = allBones.boneInfos; //mat4[] offsetMats = new mat4[this.boneIndexes.Length]; //for (int i = 0; i < this.boneIndexes.Length; i++) //{ // int index = this.boneIndexes[i]; // if (index >= 0) // { // offsetMats[i] = boneInfos[index].Bone.OffsetMatrix.ToMat4(); // } //} //this.offsetMats = offsetMats; //this.multiplys = new mat4[this.offsetMats.Length]; //this.inverseMutiplys = new mat4[this.offsetMats.Length]; //mat4 rootTransform = glm.inverse(scene.RootNode.Transform.ToMat4()); //for (int i = 0; i < this.offsetMats.Length; i++) //{ // this.multiplys[i] = rootTransform * this.transforms[i] * this.offsetMats[i]; // this.inverseMutiplys[i] = this.inversedTransforms[i] * this.offsetMats[i]; //} //Console.WriteLine("af"); }
public void ImportModel() { OpenFileDialog dlg = new OpenFileDialog() { DefaultExt = "sa1mdl", Filter = "Model Files|*.sa1mdl;*.obj;*.objf", RestoreDirectory = true }; if (dlg.ShowDialog() == DialogResult.OK) { switch (Path.GetExtension(dlg.FileName).ToLowerInvariant()) { case ".obj": case ".fbx": case ".dae": case ".objf": Assimp.AssimpContext context = new Assimp.AssimpContext(); context.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false)); Assimp.Scene scene = context.ImportFile(dlg.FileName, Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.JoinIdenticalVertices | Assimp.PostProcessSteps.FlipUVs); NJS_OBJECT newmodel = SAEditorCommon.Import.AssimpStuff.AssimpImport(scene, scene.RootNode, ModelFormat.BasicDX, LevelData.TextureBitmaps[LevelData.leveltexs].Select(a => a.Name).ToArray(), true); Model.Attach = newmodel.Attach; Model.ProcessVertexData(); Mesh = Model.Attach.CreateD3DMesh(); break; case ".sa1mdl": ModelFile mf = new ModelFile(dlg.FileName); Model.Attach = mf.Model.Attach; Model.ProcessVertexData(); Mesh = Model.Attach.CreateD3DMesh(); break; } } }
/// <summary> /// Replace the geometries in the scene with the ones contained in the given Assimp scene. /// </summary> /// <param name="scene"></param> public void ReplaceGeometries(Assimp.Scene scene) { var skinToBoneMatrices = ComputeSkinToBoneMatrices(scene); GeometryList.Clear(); Atomics.Clear(); for (var i = 0; i < scene.Meshes.Count; i++) { var assimpMesh = scene.Meshes[i]; var rootNode = FindMeshRootNode(scene.RootNode, i) ?? scene.RootNode; TransformMeshVertices(assimpMesh, rootNode); var geometryNode = new RwGeometryNode(this, assimpMesh, scene.Materials[assimpMesh.MaterialIndex], FrameList, skinToBoneMatrices, out bool singleWeight); GeometryList.Add(geometryNode); var atomicNode = new RwAtomicNode(this, 0, i, 5); if (singleWeight) { if (assimpMesh.Bones.Count != 0) { atomicNode.FrameIndex = FrameList.GetFrameIndexByName(assimpMesh.Bones[0].Name); } else if (rootNode != null) { atomicNode.FrameIndex = FrameList.GetFrameIndexByName(rootNode.Name); } } Atomics.Add(atomicNode); } mStructNode = new RwClumpStructNode(this); }
public MAT3(Assimp.Scene scene, TEX1 textures, SHP1 shapes) { InitLists(); for (int i = 0; i < scene.MeshCount; i++) { Assimp.Material meshMat = scene.Materials[scene.Meshes[i].MaterialIndex]; Materials.Material bmdMaterial = new Material(); bool hasVtxColor0 = shapes.Shapes[i].AttributeData.CheckAttribute(GXVertexAttribute.Color0); int texIndex = -1; if (meshMat.HasTextureDiffuse) { string texName = Path.GetFileNameWithoutExtension(meshMat.TextureDiffuse.FilePath); texIndex = textures.Textures.IndexOf(textures[texName]); } bmdMaterial.SetUpTev(meshMat.HasTextureDiffuse, hasVtxColor0, texIndex); m_Materials.Add(bmdMaterial); m_RemapIndices.Add(i); m_MaterialNames.Add(meshMat.Name); } FillMaterialDataBlocks(); }
/// <summary> /// /// </summary> /// <param name="aiScene"></param> /// <param name="TimeInSeconds"></param> /// <returns></returns> private static mat4[] GetBoneMatrixes(Assimp.Scene aiScene, float TimeInSeconds, AllBoneInfos allBoneInfos) { if (aiScene.AnimationCount <= 0) { return(null); } double ticksPerSecond = aiScene.Animations[0].TicksPerSecond; if (ticksPerSecond == 0) { ticksPerSecond = 25.0; } double timeInTicks = TimeInSeconds * ticksPerSecond; float animationTime = (float)(timeInTicks % aiScene.Animations[0].DurationInTicks); Assimp.Matrix4x4 transform = aiScene.RootNode.Transform; transform.Inverse(); ReadNodeHeirarchy(animationTime, aiScene.RootNode, aiScene.Animations[0], mat4.identity(), allBoneInfos); int boneCount = allBoneInfos.boneInfos.Length; var result = new mat4[boneCount]; for (int i = 0; i < boneCount; i++) { result[i] = allBoneInfos.boneInfos[i].finalTransformation; } return(result); }
public void ImportModel(string filePath, bool legacyImport = false) { NJS_OBJECT newmodel; // Old OBJ import (with vcolor face) for NodeTable and legacy import if (legacyImport) { newmodel = new NJS_OBJECT { Attach = SAModel.Direct3D.Extensions.obj2nj(filePath, LevelData.TextureBitmaps != null ? LevelData.TextureBitmaps[LevelData.leveltexs].Select(a => a.Name).ToArray() : null), }; COL.Model.Attach = newmodel.Attach; COL.Model.ProcessVertexData(); Visible = true; Solid = true; mesh = COL.Model.Attach.CreateD3DMesh(); return; } Assimp.AssimpContext context = new Assimp.AssimpContext(); context.SetConfig(new Assimp.Configs.FBXPreservePivotsConfig(false)); Assimp.Scene scene = context.ImportFile(filePath, Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.JoinIdenticalVertices | Assimp.PostProcessSteps.FlipUVs); newmodel = SAEditorCommon.Import.AssimpStuff.AssimpImport(scene, scene.RootNode, ModelFormat.BasicDX, LevelData.TextureBitmaps[LevelData.leveltexs].Select(a => a.Name).ToArray(), true); COL.Model.Attach = newmodel.Attach; COL.Model.ProcessVertexData(); Visible = true; Solid = true; mesh = COL.Model.Attach.CreateD3DMesh(); }
public SkeletonModel(Assimp.Scene scene, AllBoneInfos allBoneInfos) { this.scene = scene; this.allBones = allBoneInfos; GeneratePositions(scene); GenerateBoneIndexes(this.nodes, allBoneInfos); }
internal static void CopyNodesWithMeshes(Assimp.Scene pScene, Assimp.Node node, ref List <SceneObject> meshArr) { // if node has meshes, create a new scene object for it if (node.HasMeshes) { foreach (int i in node.MeshIndices) { SceneObject so = new SceneObject(); so.nodeName = node.Name; if (node.Parent != null) { so.parentNodeName = node.Parent.Name; } so.pMesh = pScene.Meshes[i]; so.transform = node.Transform; so.transform.Transpose(); meshArr.Add(so); } } // continue for all child nodes if (node.HasChildren) { foreach (Assimp.Node childNode in node.Children) { CopyNodesWithMeshes(pScene, childNode, ref meshArr); } } }
private void exportToAssimp(object sender, EventArgs e) { Debug.WriteLine("Exporting to assimp"); if (RenderState.rootObject != null) { Assimp.AssimpContext ctx = new Assimp.AssimpContext(); Dictionary <int, int> meshImportStatus = new Dictionary <int, int>(); Assimp.Scene aScene = new Assimp.Scene(); Assimp.Node rootNode = RenderState.rootObject.assimpExport(ref aScene, ref meshImportStatus); aScene.RootNode = rootNode; //add a single material for now Assimp.Material aMat = new Assimp.Material(); aMat.Name = "testMaterial"; aScene.Materials.Add(aMat); Assimp.ExportFormatDescription[] supported_formats = ctx.GetSupportedExportFormats(); //Assimp.Scene blenderScene = ctx.ImportFile("SimpleSkin.gltf"); //ctx.ExportFile(blenderScene, "SimpleSkin.glb", "glb2"); try { ctx.ExportFile(aScene, "test.glb", "glb2"); //ctx.ExportFile(aScene, "test.fbx", "fbx"); } catch (Exception ex) { Console.WriteLine(ex.Message); } } }
private void OpenFile(string filename) { var importer = new Assimp.AssimpImporter(); Assimp.Scene aiScene = null; try { aiScene = importer.ImportFile(filename, Assimp.PostProcessSteps.GenerateSmoothNormals | Assimp.PostProcessSteps.Triangulate | Assimp.PostProcessSteps.FlipUVs); } catch (Exception ex) { MessageBox.Show(ex.Message); return; } var container = new AssimpSceneContainer(aiScene, filename); CreateAnimationNodes(aiScene, container); CreateSkeletonNode(aiScene, container); CreateJointNode(aiScene, container); { this.cmbAnimationIndex.Items.Clear(); int count = container.aiScene.AnimationCount; for (int i = 0; i < count; i++) { this.cmbAnimationIndex.Items.Add(string.Format("Animation {0}", i)); } } }
private static LandModelSA2 ConvertDisplayModel(Assimp.Scene aiScene, List <MaterialBuildInfo> materialBuildInfos, Assimp.Node aiMeshNode) { var displayModel = new LandModelSA2(); displayModel.Flags |= SurfaceFlags.Visible; displayModel.RootNode = ConvertNode(aiMeshNode, aiScene.Meshes, materialBuildInfos, ConvertDisplayGeometry); var displayGeometry = ( Geometry )displayModel.RootNode.Geometry; displayModel.Bounds = displayGeometry.Bounds; //var min = new Vector3( float.MaxValue, float.MaxValue, float.MaxValue ); //var max = new Vector3( float.MinValue, float.MinValue, float.MinValue ); //var modelWorldTransform = displayModel.RootNode.WorldTransform; //foreach ( var node in displayModel.RootNode.EnumerateAllNodes() ) //{ // if ( node.Geometry == null ) // continue; // var geometry = ( ( Geometry ) node.Geometry ); // var positionBuffer = ( VertexPositionBuffer )geometry.VertexBuffers.Single( x => x.Type == VertexAttributeType.Position ); // foreach ( var vertexPosition in positionBuffer.Elements ) // { // var position = vertexPosition; // min.X = Math.Min( min.X, position.X ); // min.Y = Math.Min( min.Y, position.Y ); // min.Z = Math.Min( min.Z, position.Z ); // max.X = Math.Max( max.X, position.X ); // max.Y = Math.Max( max.Y, position.Y ); // max.Z = Math.Max( max.Z, position.Z ); // } //} //displayModel.Bounds = Bounds.Calculate( min, max ); return(displayModel); }
public void LoadContent(GraphicsDevice device, ContentManager content) { LoadData loadData = LoadMapData(device, filepath); tiles = loadData.Tiles; startPosition = loadData.StartPosition; minimap = loadData.Minimap; var importer = new Assimp.AssimpImporter(); string fileName = System.IO.Path.GetFullPath(content.RootDirectory + "/wall.3ds"); Assimp.Scene scene = importer.ImportFile(fileName, Assimp.PostProcessSteps.MakeLeftHanded); wallModel = new Model(scene, device, content); fileName = System.IO.Path.GetFullPath(content.RootDirectory + "/floor.3ds"); scene = importer.ImportFile(fileName, Assimp.PostProcessSteps.MakeLeftHanded); floorModel = new Model(scene, device, content); fileName = System.IO.Path.GetFullPath(content.RootDirectory + "/floorKey.3ds"); scene = importer.ImportFile(fileName, Assimp.PostProcessSteps.MakeLeftHanded); floorKeyModel = new Model(scene, device, content); fileName = System.IO.Path.GetFullPath(content.RootDirectory + "/ceiling.3ds"); scene = importer.ImportFile(fileName, Assimp.PostProcessSteps.MakeLeftHanded); ceilingModel = new Model(scene, device, content); fileName = System.IO.Path.GetFullPath(content.RootDirectory + "/door.3ds"); scene = importer.ImportFile(fileName, Assimp.PostProcessSteps.MakeLeftHanded); doorModel = new Model(scene, device, content); }
private void Clear() { scene = null; materials = new List <Material>(); meshes = new List <SubMeshComponent>(); //textures = new Dictionary<string, Texture2D>(); }
public void InitAssImp(Assimp.Scene aiRoot, Scene.Entity3D root) { if (aiRoot.HasAnimations == false) { return; } _skeleton = CreateBoneTree(aiRoot.RootNode, null); Console.WriteLine("Proc bones:" + _skeleton.Name + " C:" + _skeleton.Children.Count); foreach (Assimp.Mesh mesh in aiRoot.Meshes) { foreach (Assimp.Bone bone in mesh.Bones) { if (!_bonesByName.TryGetValue(bone.Name, out Bone found)) { continue; } bool skip = (from t in _bones let bname = bone.Name where t.Name == bname select t).Any(); if (skip) { continue; } found.Offset = ToTK(bone.OffsetMatrix); _bones.Add(found); _bonesToIndex[found.Name] = _bones.IndexOf(found); } Assimp.Mesh mesh1 = mesh; foreach (string bone in _bonesByName.Keys.Where(b => mesh1.Bones.All(b1 => b1.Name != b) && b.StartsWith("Bone"))) { _bonesByName[bone].Offset = _bonesByName[bone].Parent.Offset; _bones.Add(_bonesByName[bone]); _bonesToIndex[bone] = _bones.IndexOf(_bonesByName[bone]); } } ExtractAnimations(aiRoot); const float timestep = 1.0f / 30.0f; for (int i = 0; i < Animations.Count; i++) { SetAnimationIndex(i); float dt = 0.0f; for (float ticks = 0.0f; ticks < Animations[i].Duration; ticks += Animations[i].TicksPerSecond / 30.0f) { dt += timestep; Calculate(dt); List <OpenTK.Matrix4> trans = new List <OpenTK.Matrix4>(); for (int a = 0; a < _bones.Count; a++) { OpenTK.Matrix4 rotMat = _bones[a].Offset * _bones[a].GlobalTransform; trans.Add(rotMat); } Animations[i].Transforms.Add(trans); } } Console.WriteLine("Finished loading animations with " + _bones.Count + " bones"); }
public DeviceModelCollection ReadModel(Assimp.Scene scene) { var factory = UseBasicEffects ? (DeviceMeshFactory) new ClassicMeshFactory(_Device) : new PBRMeshFactory(_Device); return(ConvertToDevice(scene, factory)); }
public void assimpExport(ref Assimp.Scene scn) { foreach (AnimData ad in Animations) { Assimp.Animation anim = ad.assimpExport(ref scn); scn.Animations.Add(anim); } }
protected static Assimp.Scene CreateDefaultScene() { var aiScene = new Assimp.Scene { RootNode = new Assimp.Node("RootNode") }; return(aiScene); }
private mat4[] GetTransforms(Assimp.Scene scene) { var list = new List <mat4>(); ParseNodeTransform(scene.RootNode, list, mat4.identity()); return(list.ToArray()); }
private vec3[] GetPositions(Assimp.Scene scene) { var list = new List <vec3>(); ParseNode(scene.RootNode, list, mat4.identity()); return(list.ToArray()); }
private int[] GetIndexes(Assimp.Scene scene, AllBoneInfos allBoneInfos) { Dictionary <string, uint> nameIndexDict = allBoneInfos.nameIndexDict; var list = new List <int>(); ParseNodeIndexes(scene.RootNode, list, nameIndexDict); return(list.ToArray()); }
private void CreateSkeletonNode(Assimp.Scene aiScene, AssimpSceneContainer container) { var rootElement = this.scene.RootNode; var model = new SkeletonModel(aiScene, container.GetAllBoneInfos()); var node = SkeletonNode.Create(model); this.skeletonNode = node; rootElement.Children.Add(node); }
public ModelContent CreateModelContent(Assimp.Scene scene, int armatureIndex) { var drawables = Flatten(scene.RootNode) .Where(item => item.HasMeshes) .SelectMany(item => CreateDrawableContent(item, scene.Meshes)) .ToArray(); return(new ModelContent(armatureIndex, drawables)); }
private void CreateJointNode(Assimp.Scene aiScene, AssimpSceneContainer container) { var rootElement = this.scene.RootNode; var model = new JointModel(aiScene, container.GetAllBoneInfos()); var node = JointNode.Create(model); node.DiffuseColor = Color.Red; this.jointNode = node; rootElement.Children.Add(node); }
internal static Mesh3D LoadFromFile(Device device, Assimp.Scene pScene, InputElement[] ieLayout) { Assimp.Node root = pScene.RootNode; List <SceneObject> meshArr = new List <SceneObject>(); CopyNodesWithMeshes(pScene, root, ref meshArr); return(LoadFromFileSUB(device, pScene, ieLayout, meshArr)); }
public static Dictionary <int, Assimp.Node> GetAnimatedNodes(Assimp.Scene aiScene) { Dictionary <int, Assimp.Node> nodes = new Dictionary <int, Assimp.Node>(); foreach (var node in aiScene.RootNode.Children) { CollectAnimated(node, nodes); } return(nodes); }
public static DeviceModelCollection ConvertToDevice(Assimp.Scene srcScene, DeviceMeshFactory meshFactory) { if (meshFactory == null) { throw new ArgumentNullException(); } var content = ConvertToContent(srcScene); return(DeviceModelCollection.CreateFrom(content, meshFactory.CreateMeshCollection)); }
public void SetUp() { var assimpNetimporter = new Assimp.AssimpContext(); Assimp.LogStream.IsVerboseLoggingEnabled = true; var logger = new Assimp.ConsoleLogStream(); logger.Attach(); assimpNetScene = assimpNetimporter.ImportFile(filename); logger.Detach(); var assimpSharpImporter = new AssimpSharp.FBX.FBXImporter(); assimpSharpScene = new AssimpSharp.Scene(); assimpSharpScene = assimpSharpImporter.ReadFile(filename); }
public static Assimp.Scene ToAssimpScene(RWScene scene) { Assimp.Scene aiScene = new Assimp.Scene(); int drawCallIdx = 0; int materialIdx = 0; int totalSplitIdx = 0; List<int> meshStartIndices = new List<int>(); foreach (RWDrawCall drawCall in scene.DrawCalls) { meshStartIndices.Add(totalSplitIdx); var mesh = scene.Meshes[drawCall.MeshIndex]; var node = scene.Nodes[drawCall.NodeIndex]; int splitIdx = 0; foreach (RWMeshMaterialSplit split in mesh.MaterialSplitData.MaterialSplits) { Assimp.Mesh aiMesh = new Assimp.Mesh(Assimp.PrimitiveType.Triangle); aiMesh.Name = string.Format("DrawCall{0}_Split{1}", drawCallIdx.ToString("00"), splitIdx.ToString("00")); aiMesh.MaterialIndex = split.MaterialIndex + materialIdx; // get split indices int[] indices = split.Indices; if (mesh.MaterialSplitData.PrimitiveType == RWPrimitiveType.TriangleStrip) indices = MeshUtilities.ToTriangleList(indices, true); // pos & nrm for (int i = 0; i < indices.Length; i++) { if (mesh.HasVertices) { var vert = Vector3.Transform(mesh.Vertices[indices[i]], node.WorldTransform); aiMesh.Vertices.Add(vert.ToAssimpVector3D()); } if (mesh.HasNormals) { var nrm = Vector3.TransformNormal(mesh.Normals[indices[i]], node.WorldTransform); aiMesh.Normals.Add(nrm.ToAssimpVector3D()); } } // tex coords if (mesh.HasTexCoords) { for (int i = 0; i < mesh.TextureCoordinateChannelCount; i++) { List<Assimp.Vector3D> texCoordChannel = new List<Assimp.Vector3D>(); for (int j = 0; j < indices.Length; j++) { texCoordChannel.Add(mesh.TextureCoordinateChannels[i][indices[j]].ToAssimpVector3D(0)); } aiMesh.TextureCoordinateChannels[i] = texCoordChannel; } } // colors if (mesh.HasColors) { List<Assimp.Color4D> vertColorChannel = new List<Assimp.Color4D>(); for (int i = 0; i < indices.Length; i++) { var color = mesh.Colors[indices[i]]; vertColorChannel.Add(new Assimp.Color4D(color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f)); } aiMesh.VertexColorChannels[0] = vertColorChannel; } // generate temporary face indices int[] tempIndices = new int[aiMesh.VertexCount]; for (int i = 0; i < aiMesh.VertexCount; i++) tempIndices[i] = i; aiMesh.SetIndices(tempIndices, 3); // add the mesh to the list aiScene.Meshes.Add(aiMesh); splitIdx++; } totalSplitIdx += splitIdx; foreach (RWMaterial mat in mesh.Materials) { Assimp.Material aiMaterial = new Assimp.Material(); aiMaterial.AddProperty(new Assimp.MaterialProperty(Assimp.Unmanaged.AiMatKeys.NAME, "Material" + (materialIdx++).ToString("00"))); if (mat.IsTextured) { aiMaterial.AddProperty(new Assimp.MaterialProperty(Assimp.Unmanaged.AiMatKeys.TEXTURE_BASE, mat.TextureReference.ReferencedTextureName + ".png", Assimp.TextureType.Diffuse, 0)); } aiScene.Materials.Add(aiMaterial); } drawCallIdx++; } // store node lookup Dictionary<RWSceneNode, Assimp.Node> nodeLookup = new Dictionary<RWSceneNode, Assimp.Node>(); // first create the root node var rootNode = new Assimp.Node("SceneRoot"); rootNode.Transform = scene.Nodes[0].Transform.ToAssimpMatrix4x4(); nodeLookup.Add(scene.Nodes[0], rootNode); for (int i = 1; i < scene.Nodes.Count - 1; i++) { var node = scene.Nodes[i]; string name = node.BoneMetadata.BoneNameID.ToString(); var aiNode = new Assimp.Node(name); aiNode.Transform = node.Transform.ToAssimpMatrix4x4(); // get the associated meshes for this node var drawCalls = scene.DrawCalls.FindAll(dc => dc.NodeIndex == i); foreach (var drawCall in drawCalls) { for (int j = 0; j < scene.Meshes[drawCall.MeshIndex].MaterialCount; j++) { aiNode.MeshIndices.Add(meshStartIndices[scene.DrawCalls.IndexOf(drawCall)] + j); } } nodeLookup[node.Parent].Children.Add(aiNode); nodeLookup.Add(node, aiNode); } aiScene.RootNode = rootNode; return aiScene; }