private static void ConvertMB() { var model = Resource.Load <Model>(Options.Input); switch (Options.OutputFormat) { case OutputFormat.PB: var modelPack = new ModelPack(); modelPack.Models.Add(model); modelPack.Save(Options.Output); break; case OutputFormat.MB: model.Save(Options.Output); break; case OutputFormat.OBJ: case OutputFormat.DAE: case OutputFormat.FBX: if (Options.OutputFormat == OutputFormat.DAE || Options.OutputFormat == OutputFormat.FBX) { FbxModelExporter.Instance.Export(model, Options.Output, FbxConfig, null); } else { AssimpModelExporter.Instance.Export(model, Options.Output); } break; default: throw new Exception("Unsupported output format"); } }
public static ModelPack ConvertFromAssimpScene(string filePath, ModelPackConverterOptions options) { // For importing textures string baseDirectoryPath = Path.GetDirectoryName(filePath); // Import scene var aiScene = AssimpSceneImporter.ImportFile(filePath); // Build textures & Materials var model = new ModelPack(options.Version); model.Textures = new TextureDictionary(options.Version); model.Materials = new MaterialDictionary(options.Version); foreach (var aiSceneMaterial in aiScene.Materials) { var material = ConvertMaterialAndTextures(aiSceneMaterial, options, baseDirectoryPath, model.Textures); model.Materials.Add(material); } // Create scene var sceneConverterOptions = new ModelConverterOptions() { Version = options.Version, ConvertSkinToZUp = options.ConvertSkinToZUp, GenerateVertexColors = options.GenerateVertexColors, MinimalVertexAttributes = options.MinimalVertexAttributes, }; model.Model = ModelConverter.ConvertFromAssimpScene(aiScene, sceneConverterOptions); return(model); }
public GLModel(ModelPack modelPack, MaterialTextureCreator textureCreator) { ModelPack = modelPack; var nodes = modelPack.Model.Nodes.ToList(); Nodes = nodes.Select(x => new GLNode(x)).ToList(); Materials = modelPack.Materials?.ToDictionary(x => x.Key, y => new GLMaterial(y.Value, textureCreator)) ?? new Dictionary <string, GLMaterial>(); foreach (var glNode in Nodes) { glNode.Parent = Nodes.FirstOrDefault(x => x.Node == glNode.Node.Parent); if (!glNode.Node.HasAttachments) { continue; } foreach (var attachment in glNode.Node.Attachments) { if (attachment.Type != NodeAttachmentType.Mesh) { continue; } var glMesh = new GLMesh(attachment.GetValue <Mesh>(), glNode.Node.WorldTransform, modelPack.Model.Bones, Nodes, Materials); glNode.Meshes.Add(glMesh); } } }
static void Initialize(this MMDRendererComponent renderer, ModelPack modelPack) { renderer.bones.Clear(); renderer.boneMatricesData = new Matrix4x4[modelPack.bones.Count]; foreach (var bone in modelPack.bones) { renderer.bones.Add(bone.GetClone()); } renderer.rigidBodyDescs.Clear(); renderer.rigidBodyDescs.AddRange(modelPack.rigidBodyDescs); for (int i = 0; i < modelPack.rigidBodyDescs.Count; i++) { var rigidBodyDesc = renderer.rigidBodyDescs[i]; if (rigidBodyDesc.Type != RigidBodyType.Kinematic && rigidBodyDesc.AssociatedBoneIndex != -1) { renderer.bones[rigidBodyDesc.AssociatedBoneIndex].IsPhysicsFreeBone = true; } } renderer.jointDescs.Clear(); renderer.jointDescs.AddRange(modelPack.jointDescs); renderer.Bake(); }
public static void ExportFile(ModelPack modelPack, string path) { var exporter = new ModelPackExporter(); var scene = exporter.ConvertModelPack(modelPack, path); ExportFile(scene, path); }
public static void Reload(this MMDRendererComponent rendererComponent, ModelPack modelPack) { rendererComponent.POSkinning = null; rendererComponent.PODraw = null; rendererComponent.ParticleCompute = null; rendererComponent.POParticleDraw = null; ReloadModel(rendererComponent, modelPack); }
private static void ConvertPB() { var modelPack = new ModelPack(Options.Input); switch (Options.OutputFormat) { case OutputFormat.PB: modelPack.Save(Options.Output); break; case OutputFormat.MB: for (int i = 0; i < modelPack.Models.Count; i++) { modelPack.Models[i].Save(modelPack.Models.Count == 1 ? Options.Output : $"{Path.GetFileNameWithoutExtension( Options.Output )}_{i}.MB"); } break; case OutputFormat.OBJ: case OutputFormat.DAE: case OutputFormat.FBX: for (int i = 0; i < modelPack.Models.Count; i++) { var modelOutfilePath = modelPack.Models.Count == 1 ? Options.Output : $"{Path.GetFileNameWithoutExtension( Options.Output )}_{i}.{Options.OutputFormat}"; if (Options.OutputFormat == OutputFormat.DAE || Options.OutputFormat == OutputFormat.FBX) { FbxModelExporter.Instance.Export(modelPack.Models[i], modelOutfilePath, FbxConfig, modelPack.TexturePack); } else { AssimpModelExporter.Instance.Export(modelPack.Models[i], modelOutfilePath, modelPack.TexturePack); } if (Options.Assimp.OutputPbMotion) { for (int j = 0; j < modelPack.MotionPacks.Count; j++) { for (int k = 0; k < modelPack.MotionPacks[j].Motions.Count; k++) { var outfilePath = modelPack.MotionPacks.Count == 1 ? $"{Path.GetFileNameWithoutExtension( Options.Output )}_m_{j}.{Options.OutputFormat}" : $"{Path.GetFileNameWithoutExtension( Options.Output )}_mp_{j}_m_{k}.{Options.OutputFormat}"; AssimpMotionExporter.Instance.Export(modelPack.Models[i], modelPack.MotionPacks[j].Motions[k], outfilePath); } } } } break; default: throw new Exception("Unsupported output format"); } }
static void Main(string[] args) { if (args.Length > 0) { ModelPack mpk = new ModelPack(args[0]); mpk.Extract(CtrVrm.FromFile("ui_textures.vram")); //Console.ReadKey(); } }
private static void GenerateMaterialPresets() { var paths = Directory.EnumerateFiles("unique_models", "*.PB", SearchOption.AllDirectories).ToList(); Directory.CreateDirectory("material_presets"); var materialCache = new Dictionary <int, (int Id, bool IsTextured, bool HasOverlay)>(); var done = 0; Parallel.ForEach(paths, new ParallelOptions() { MaxDegreeOfParallelism = 8 }, (path) => { Console.WriteLine(Path.GetFileName(path)); var modelPack = new ModelPack(path); foreach (var model in modelPack.Models) { foreach (var material in model.Materials) { var materialHash = material.GetPresetHashCode(); var isTextured = material.TextureId.HasValue; var hasOverlay = material.OverlayTextureIds != null; lock ( materialCache ) { var inCache = materialCache.ContainsKey(materialHash); if (!inCache || materialCache[materialHash].IsTextured != isTextured || materialCache[materialHash].HasOverlay != hasOverlay) { var id = materialCache.Count; if (inCache) { id = materialCache[materialHash].Id; } var json = JsonConvert.SerializeObject(material, Formatting.Indented); var name = id.ToString(); if (isTextured) { name += "_d"; } if (hasOverlay) { name += "_o"; } File.WriteAllText($"material_presets\\{name}.json", json); if (!inCache) { materialCache[materialHash] = (materialCache.Count, isTextured, hasOverlay); }
private static void RemoveChunks() { foreach (var gmd in Directory.GetFiles(Input.retargetFolder, "*.GMD", SearchOption.TopDirectoryOnly)) { var modelPack = ModuleImportUtilities.ImportFile <ModelPack>(gmd); var newModelPack = new ModelPack(); newModelPack.Version = modelPack.Version; newModelPack.Textures = modelPack.Textures; newModelPack.Materials = modelPack.Materials; newModelPack.Model = modelPack.Model; newModelPack.AnimationPack = modelPack.AnimationPack; newModelPack.Save(gmd); } }
static async Task LoadPMX(StorageFile file, StorageFolder folder, ModelPack pack, ProcessingList processingList) { string path = file.Path; BinaryReader reader = new BinaryReader((await file.OpenReadAsync()).AsStreamForRead()); pack.Reload2(reader); pack.fullPath = path; pack.folder = folder; pack.relativePath = file.Name; reader.Dispose(); processingList.AddObject(pack.GetMesh()); pack.Status = GraphicsObjectStatus.loaded; pack.LoadTask = null; }
static void LoadMesh(this MMDRendererComponent renderer, ModelPack modelPack) { renderer.Materials.Clear(); for (int i = 0; i < modelPack.Materials.Count; i++) { var mat = modelPack.Materials[i].GetClone(); renderer.Materials.Add(mat); } renderer.weights = new float[modelPack.morphs.Count]; var mesh = modelPack.GetMesh(); renderer.meshPath = modelPack.fullPath; renderer.meshPositionCache = new Vector3[mesh.GetVertexCount()]; new Span <Vector3>(modelPack.position).CopyTo(renderer.meshPositionCache); }
static void LoadAnimationStates(this AnimationStateComponent component, ModelPack modelPack) { component.cachedBoneKeyFrames.Clear(); for (int i = 0; i < modelPack.bones.Count; i++) { component.cachedBoneKeyFrames.Add((Vector3.Zero, Quaternion.Identity)); } int morphCount = modelPack.morphs.Count; component.Weights.Load(morphCount); component.stringToMorphIndex.Clear(); for (int i = 0; i < morphCount; i++) { component.stringToMorphIndex[modelPack.morphs[i].Name] = i; } }
// Comparison methods private void CompareModels(ModelPack a, ModelPack b) { if (a == null || b == null) { Assert.IsTrue(a == null ? (b == null) : (b != null)); return; } Assert.AreEqual(a.ResourceType, b.ResourceType); Assert.AreEqual(a.Version, b.Version); CompareTextureDictionaries(a.Textures, a.Textures); CompareMaterialDictionaries(a.Materials, b.Materials); CompareScenes(a.Model, b.Model); CompareAnimationPackage(a.AnimationPack, b.AnimationPack); }
public static void LoadPmx(this GameObject gameObject, ModelPack modelPack) { gameObject.Name = modelPack.name; gameObject.Description = modelPack.description; var renderer = new MMDRendererComponent(); gameObject.AddComponent(renderer); renderer.skinning = true; renderer.morphs.Clear(); renderer.morphs.AddRange(modelPack.morphs); var animationState = new AnimationStateComponent(); gameObject.AddComponent(animationState); animationState.LoadAnimationStates(modelPack); renderer.Initialize(modelPack); renderer.LoadMesh(modelPack); renderer.SetTransform(gameObject.Transform); }
private Ai.Scene ConvertModelPack(ModelPack modelPack, string path) { Init(path); if (modelPack.Textures != null) { ConvertTextures(modelPack.Textures); } if (modelPack.Materials != null) { ConvertMaterials(modelPack.Materials); } if (modelPack.Model != null) { ConvertModel(modelPack.Model); } return(mAiScene); }
private static void ReplaceF1Test() { var modelPack = new ModelPack(); var model = new Model(); model.Nodes.Add(new Node { Name = "model" }); modelPack.Models.Add(model); modelPack.Replace("f1test.fbx"); var lb = new LBFileSystem(); lb.Load(@"D:\Modding\DDS3\Nocturne\_HostRoot\dds3data\fld\f\f037\_f037_027.LB"); var f1Handle = lb.GetHandle("F1"); FieldScene f1; using (var stream = lb.OpenFile(f1Handle)) f1 = new FieldScene(stream, true); f1.Objects.RemoveAll(x => x.ResourceType == FieldObjectResourceType.Model); f1.Objects.Clear(); f1.Objects.Add(new FieldObject() { Id = 0, Name = "model", Transform = new FieldObjectTransform(), Resource = modelPack.Models[0] }); ExportObj(f1); lb.AddFile(f1Handle, f1.Save(), true, ConflictPolicy.Replace); if (modelPack.TexturePack != null) { var tbHandle = lb.GetHandle("TBN"); lb.AddFile(tbHandle, modelPack.TexturePack.Save(), true, ConflictPolicy.Replace); } lb.Save(@"D:\Modding\DDS3\Nocturne\_HostRoot\dds3data\fld\f\f037\f037_027.LB"); }
public static void ExportObj(ModelPack modelPack, string fileName = "test.obj") { var vertexBaseIndex = 0; using (var writer = File.CreateText(fileName)) { foreach (var model in modelPack.Models) { foreach (var node in model.Nodes) { if (node.Geometry == null) { continue; } if (node.Geometry.Meshes != null) { for (var meshIndex = 0; meshIndex < node.Geometry.Meshes.Count; meshIndex++) { var mesh = node.Geometry.Meshes[meshIndex]; writer.WriteLine($"// node '{node.Name}' mesh ({mesh.Type}) #{meshIndex}"); WriteMesh(writer, model, node, mesh, meshIndex, false, ref vertexBaseIndex); } } if (node.Geometry.TranslucentMeshes != null) { for (var meshIndex = 0; meshIndex < node.Geometry.TranslucentMeshes.Count; meshIndex++) { var mesh = node.Geometry.TranslucentMeshes[meshIndex]; writer.WriteLine($"// node '{node.Name}' mesh(XLU) ({mesh.Type}) #{meshIndex}"); WriteMesh(writer, model, node, mesh, meshIndex, true, ref vertexBaseIndex); } } } } } }
public static async Task LoadEntityIntoScene(Coocoo3DMain appBody, Scene scene, StorageFile pmxFile, StorageFolder storageFolder) { string pmxPath = pmxFile.Path; string relatePath = pmxFile.Name; ModelPack pack = null; lock (appBody.mainCaches.ModelPackCaches) { pack = appBody.mainCaches.ModelPackCaches.GetOrCreate(pmxPath); if (pack.LoadTask == null && pack.Status != GraphicsObjectStatus.loaded) { pack.LoadTask = Task.Run(async() => { BinaryReader reader = new BinaryReader((await pmxFile.OpenReadAsync()).AsStreamForRead()); pack.lastModifiedTime = (await pmxFile.GetBasicPropertiesAsync()).DateModified; pack.Reload2(reader); pack.folder = storageFolder; pack.relativePath = relatePath; reader.Dispose(); appBody.ProcessingList.AddObject(pack.GetMesh()); pack.Status = GraphicsObjectStatus.loaded; pack.LoadTask = null; }); } } if (pack.Status != GraphicsObjectStatus.loaded && pack.LoadTask != null) { await pack.LoadTask; } MMD3DEntity entity = new MMD3DEntity(); entity.Reload2(appBody.ProcessingList, pack, GetTextureList(appBody, storageFolder, pack.pmx), pmxPath); scene.AddSceneObject(entity); appBody.RequireRender(); appBody.mainCaches.ReloadTextures(appBody.ProcessingList, appBody.RequireRender); }
static void ConvertFile(string s) { string basepath = Path.GetDirectoryName(s); string name = Path.GetFileNameWithoutExtension(s); string ext = Path.GetExtension(s).ToLower(); switch (ext) { case ".lev": { Scene scn = Scene.FromFile(s); scn.quads = scn.quads.OrderBy(o => o.id).ToList(); scn.Export(basepath, ExportFlags.All); break; } case ".ctr": case ".dyn": { CtrModel d = new CtrModel(s); d.Export(basepath); break; } case ".mpk": { ModelPack mpk = new ModelPack(s); mpk.Extract(Path.Combine(basepath, name), CtrVrm.FromFile(Path.Combine(basepath, "shared.vrm"))); break; } } Console.WriteLine("Done!"); }
void LoadEntityIntoScene(FileInfo modelFile) { string path = modelFile.FullName; ModelPack modelPack = caches.GetModel(path); foreach (var tex in modelPack.textures) { caches.PreloadTexture(tex); } if (modelPack.pmx != null) { GameObject gameObject = new GameObject(); gameObject.LoadPmx(modelPack); scene.AddGameObject(gameObject); } else { GameObject gameObject = new GameObject(); gameObject.Name = Path.GetFileNameWithoutExtension(path); modelPack.LoadMeshComponent(gameObject); scene.AddGameObject(gameObject); } gameDriverContext.RequireRender(false); }
private static void OpenAndSaveModelPackBatchTest() { if (!Directory.Exists("unique_models")) { FindUniqueFiles("unique_models", @"D:\Modding\DDS3", ".PB"); } if (!Directory.Exists("unique_lb")) { FindUniqueFiles("unique_lb", @"D:\Modding\DDS3", ".LB"); } if (!Directory.Exists("unique_lb_extracted")) { Directory.CreateDirectory("unique_lb_extracted"); var checksums = new HashSet <string>(); Parallel.ForEach(Directory.EnumerateFiles("unique_lb"), (path) => { var fileName = Path.GetFileNameWithoutExtension(path); var outPath = $"unique_lb_extracted\\"; Directory.CreateDirectory(outPath); using (var lb = new AtlusFileSystemLibrary.FileSystems.LB.LBFileSystem()) { lb.Load(path); foreach (var file in lb.EnumerateFiles()) { var info = lb.GetInfo(file); using (var stream = lb.OpenFile(file)) { var checksum = GetChecksum(stream); stream.Position = 0; var extract = false; lock ( checksums ) { if (!checksums.Contains(checksum)) { checksums.Add(checksum); extract = true; } } if (extract) { var nameParts = Path.GetFileNameWithoutExtension(path).Split(new[] { '_' }); Array.Resize(ref nameParts, nameParts.Length - 1); using (var fileStream = File.Create(Path.Combine(outPath, string.Concat(nameParts) + "_" + file + "_" + checksum + "." + info.Extension) )) { Console.WriteLine($"Extracting: {fileName} #{file} ({info.UserId:D2}, {info.Extension})"); stream.CopyTo(fileStream); } } } } } }); } var uniqueValues = new HashSet <MeshFlags>(); var frequencyMap = new ConcurrentDictionary <MeshFlags, int>(); var paths = Directory.EnumerateFiles("unique_models", "*.PB", SearchOption.AllDirectories).ToList(); var done = 0; //foreach ( var path in paths ) Parallel.ForEach(paths, new ParallelOptions() { MaxDegreeOfParallelism = 16 }, (path) => { Console.WriteLine(Path.GetFileName(path)); var modelPack = new ModelPack(path); new ModelPack(modelPack.Save()); //modelPack.Save( path + ".out" ); //new ModelPack( path + ".out" ); //ExportObj( modelPack, Path.GetFileNameWithoutExtension( path ) + ".obj" ); } ); //var modelPack = new ModelPack( @"D:\Programming\Repos\DDS3-Model-Studio\Source\DDS3ModelLibraryCLI\bin\Debug\unique_models\tiaki_DF1D93D2EC3ED36D63239A1A2B27ED1745DA9991F231884EA7BC5FAF291F74AA.PB" ); //modelPack.Save( @"D:\Programming\Repos\DDS3-Model-Studio\Source\DDS3ModelLibraryCLI\bin\Debug\unique_models\tiaki_DF1D93D2EC3ED36D63239A1A2B27ED1745DA9991F231884EA7BC5FAF291F74AA.PB" + ".out" ); //foreach ( var kvp in frequencyMap.OrderBy( x => x.Value ) ) //{ // Console.WriteLine( kvp.Value + " " + kvp.Key ); //} //var paths = Directory.EnumerateFiles( "unique_models", "*.PB", SearchOption.AllDirectories ).ToList(); //var done = 0; //Parallel.ForEach( paths, new ParallelOptions() { MaxDegreeOfParallelism = 8 }, ( path ) => //{ // //Console.WriteLine( Path.GetFileName( path ) ); // var modelPack = new ModelPack( path ); // //modelPack.Save( path + ".out" ); // //File.Delete( path + ".out" ); // //modelPack.Save(); //} ); //var done = 0; //Parallel.ForEach( paths, new ParallelOptions() { MaxDegreeOfParallelism = 8 }, ( path ) => //{ // Console.WriteLine( Path.GetFileName( path ) ); // var outPath = "unique_models\\" + Path.GetFileName( path ) + ".PB"; // if ( Path.GetExtension( path ) == ".PAC" ) // { // using ( var reader = new EndianBinaryReader( path, Endianness.Little ) ) // { // reader.Position = 0x24; // var size = reader.ReadInt32(); // reader.Position += 4; // var offset = reader.ReadInt32(); // using ( var fileStream = File.Create( outPath ) ) // new StreamView( reader.BaseStream, offset, size ).CopyTo( fileStream ); // } // } // else // { // File.Copy( path, outPath, true ); // } //} ); }
private static void OpenAndSaveModelPackTest() { var modelPack = new ModelPack(@"..\..\..\..\Resources\player_a.PB"); modelPack.Save(@"D:\Modding\DDS3\Nocturne\_HostRoot\dds3data\model\field\player_a.PB"); }
private static void Main(string[] args) { { File.Delete("test.fbx"); var modelPack = new ModelPack(@"D:\dumps\smt3_ntsc\DDS3\model\field\player_a.PB"); //var modelPack = new ModelPack( @"D:\dumps\smt3_ntsc\DDS3\model\devil\on\0x126_on.PB"); FbxModelExporter.Instance.Export(modelPack.Models[0], "test.fbx", modelPack.TexturePack); return; //AssimpModelExporter.Instance.Export( modelPack.Models[ 0 ], "player_a.dae", modelPack.TexturePack ); //for ( var i = 0; i < modelPack.MotionPacks[ 0 ].Motions.Count; i++ ) //{ // var motion = modelPack.MotionPacks[ 0 ].Motions[ i ]; // if ( motion == null ) // continue; // AssimpMotionExporter.Instance.Export( modelPack.Models[ 0 ], motion, $"player_a_motion_{i:D2}.dae" ); //} var newMotion = AssimpMotionImporter.Instance.Import(@"D:\Users\smart\Desktop\nocturne_player_a_fortnite.fbx", new AssimpMotionImporter.Config { NodeIndexResolver = n => modelPack.Models[0].Nodes.FindIndex(x => x.Name == n) }); for (int i = 0; i < modelPack.MotionPacks[0].Motions.Count; i++) { modelPack.MotionPacks[0].Motions[i] = newMotion; } modelPack.Save(@"D:\Modding\DDS3\Nocturne\_HostRoot\dds3data\model\field\player_a.PB"); } { var lb = new LBFileSystem(); lb.Load(@"D:\Modding\DDS3\Nocturne\_HostRoot\dds3data\fld\f\f037\_f037_027.LB"); var f1Handle = lb.GetHandle("F1"); FieldScene f1; using (var stream = lb.OpenFile(f1Handle)) f1 = new FieldScene(stream, true); foreach (var obj in f1.Objects) { switch (obj.ResourceType) { case FieldObjectResourceType.Model: { var model = ( Model )obj.Resource; foreach (var material in model.Materials) { if (material.TextureId.HasValue) { material.TextureId = 0; } material.Color1 = material.Color2 = material.Color3 = material.Color4 = material.Color5 = null; material.Float1 = null; material.FloatArray1 = material.FloatArray2 = material.FloatArray3 = null; } foreach (var node in model.Nodes) { if (node.Geometry == null) { continue; } foreach (var _mesh in node.Geometry.Meshes) { if (_mesh is MeshType1 mesh) { foreach (var batch in mesh.Batches) { batch.Flags &= ~MeshFlags.Normal; batch.Flags &= ~MeshFlags.Color; } } } } } break; case FieldObjectResourceType.Type3: break; case FieldObjectResourceType.TextureListFileName: break; case FieldObjectResourceType.Effect: break; case FieldObjectResourceType.Light: break; } } ExportObj(f1); lb.AddFile(f1Handle, f1.Save(), true, ConflictPolicy.Replace); var tbHandle = lb.GetHandle("TBN"); var texturePack = new TexturePack(); texturePack.Textures.Add(new Texture(new Bitmap(@"D:\Modding\Tools\magenta.png"))); lb.AddFile(tbHandle, texturePack.Save(), true, ConflictPolicy.Replace); lb.Save(@"D:\Modding\DDS3\Nocturne\_HostRoot\dds3data\fld\f\f037\f037_027.LB"); } //OpenAndSaveModelPackTest(); //ReplaceF1Test(); //ReplaceModelTest(); //OpenAndSaveModelPackBatchTest(); //return; //ExportObj( new ModelPack( @"D:\Modding\DDS3\Nocturne\_HostRoot\dds3data\model\field\player_b.PB" ) ); //return; //OpenAndSaveModelPackBatchTest();return; //OpenAndSaveFieldSceneBatchTest();return; //ReplaceModelTest();return; //var modelPack = new ModelPack( @"..\..\..\..\Resources\player_a.PB" ); //var modelPack = new ModelPack( @"D:\Modding\DDS3\Nocturne\_HostRoot\dds3data\model\field\player_a.PB" ); //using ( var writer = File.CreateText( "test.obj" ) ) //{ // var vertexBaseIndex = 0; // foreach ( var model in modelPack.Models ) // { // foreach ( var node in model.Nodes ) // { // if ( node.Geometry == null ) // continue; // for ( var meshIndex = 0; meshIndex < node.Geometry.Meshes.Count; meshIndex++ ) // { // var _mesh = node.Geometry.Meshes[ meshIndex ]; // if ( _mesh.Type != MeshType.Type7 ) // continue; // var mesh = ( MeshType7 ) _mesh; // var positions = new Vector3[mesh.VertexCount]; // var normals = new Vector3[positions.Length]; // var weights = new List<(short NodeIndex, float Weight)>[positions.Length]; // var texCoords = new Vector2[positions.Length]; // var batchVertexBaseIndex = 0; // foreach ( var batch in mesh.Batches ) // { // for ( var nodeBatchIndex = 0; nodeBatchIndex < batch.NodeBatches.Count; nodeBatchIndex++ ) // { // var nodeBatch = batch.NodeBatches[ nodeBatchIndex ]; // var nodeWorldTransform = model.Nodes[ nodeBatch.NodeIndex ].WorldTransform; // for ( int i = 0; i < nodeBatch.Positions.Length; i++ ) // { // var position = new Vector3( nodeBatch.Positions[i].X, nodeBatch.Positions[i].Y, // nodeBatch.Positions[i].Z ); // var weight = nodeBatch.Positions[i].W; // var weightedNodeWorldTransform = nodeWorldTransform * weight; // var weightedWorldPosition = Vector3.Transform( position, weightedNodeWorldTransform ); // positions[batchVertexBaseIndex + i] += weightedWorldPosition; // if ( weights[batchVertexBaseIndex + i] == null ) // weights[batchVertexBaseIndex + i] = new List<(short NodeIndex, float Weight)>(); // weights[batchVertexBaseIndex + i].Add( (nodeBatch.NodeIndex, weight) ); // normals[batchVertexBaseIndex + i] += Vector3.TransformNormal( nodeBatch.Normals[i], weightedNodeWorldTransform ); // } // } // Array.Copy( batch.TexCoords, 0, texCoords, batchVertexBaseIndex, batch.TexCoords.Length ); // //foreach ( var position in positions ) // //{ // // writer.WriteLine( $"v {position.X} {position.Y} {position.Z}" ); // //} // //foreach ( var normal in normals ) // //{ // // writer.WriteLine( $"vn {normal.X} {normal.Y} {normal.Z}" ); // //} // //foreach ( var texCoord in batch.TexCoords ) // //{ // // writer.WriteLine( $"vt {texCoord.X} {texCoord.Y}" ); // //} // batchVertexBaseIndex += batch.VertexCount; // } // foreach ( var position in positions ) // { // writer.WriteLine( $"v {position.X} {position.Y} {position.Z}" ); // } // foreach ( var normal in normals ) // { // writer.WriteLine( $"vn {normal.X} {normal.Y} {normal.Z}" ); // } // foreach ( var texCoord in texCoords ) // { // writer.WriteLine( $"vt {texCoord.X} {texCoord.Y}" ); // } // //// Find unique node indices used by the mesh (max 4 per mesh!) // //var usedNodeIndices = weights.SelectMany( x => x.Select( y => y.NodeIndex ) ).Distinct().ToList(); // //// Calculate node index usage frequency // //var usedNodeIndicesFrequency = new Dictionary<int, int>(); // //for ( int i = 0; i < usedNodeIndices.Count; i++ ) // // usedNodeIndicesFrequency[usedNodeIndices[i]] = 0; // //for ( int j = 0; j < positions.Length; j++ ) // //{ // // foreach ( var (nodeIndex, _) in weights[j] ) // // ++usedNodeIndicesFrequency[nodeIndex]; // //} // //// Sort used node indices by frequency // //usedNodeIndices = usedNodeIndices.OrderBy( x => usedNodeIndicesFrequency[ x ] ).ToList(); // //// Start building batches // //var vertexIndexRemap = new Dictionary<int, int>(); // //var batches = new List<MeshType7Batch>(); // //batchVertexBaseIndex = 0; // //while ( vertexIndexRemap.Count < positions.Length ) // //{ // // var batchVertexCount = Math.Min( 24, positions.Length - vertexIndexRemap.Count ); // // var batch = new MeshType7Batch(); // // var batchVertexIndexRemap = new Dictionary<int, int>(); // // var batchTexCoords = new List<Vector2>(); // // // req. all vertices to use the same set of node indices // // for ( var i = 0; i < usedNodeIndices.Count; i++ ) // // { // // var nodeIndex = usedNodeIndices[i]; // // var nodeWorldTransform = model.Nodes[nodeIndex].WorldTransform; // // var nodeWorldTransformInv = nodeWorldTransform.Inverted(); // // // get all verts with this index // // var nodePositions = new List<Vector4>(); // // var nodeNormals = new List<Vector3>(); // // for ( int j = 0; j < positions.Length; j++ ) // // { // // // Skip this vertex if it has already been processed before // // if ( vertexIndexRemap.ContainsKey( j ) ) // // continue; // // foreach ( (short NodeIndex, float Weight) in weights[j] ) // // { // // if ( NodeIndex != nodeIndex ) // // continue; // // // Transform position and normal to model space // // var position = Vector3.Transform( positions[j], nodeWorldTransformInv ); // // var normal = Vector3.TransformNormal( normals[j], nodeWorldTransformInv ); // // // Add entry to vertex remap, and add the model space positions and normals to our lists // // batchVertexIndexRemap[j] = batchVertexBaseIndex + nodePositions.Count; // // nodePositions.Add( new Vector4( position, Weight ) ); // // nodeNormals.Add( normal ); // // if ( i == 0 ) // // { // // // Only add this once, of course // // batchTexCoords.Add( texCoords[ j ] ); // // } // // // Stop looking if we've reached our vertex count // // if ( nodePositions.Count == batchVertexCount ) // // goto end; // // } // // } // // end: // // batch.NodeBatches.Add( new MeshType7NodeBatch() // // { // // NodeIndex = nodeIndex, // // Positions = nodePositions.ToArray(), // // Normals = nodeNormals.ToArray() // // }); // // } // // batch.TexCoords = batchTexCoords.ToArray(); // // foreach ( var i in batchVertexIndexRemap ) // // vertexIndexRemap.Add( i.Key, i.Value ); // // Debug.Assert( batch.NodeBatches.Count > 0 ); // // Debug.Assert( batch.NodeBatches.TrueForAll( x => x.VertexCount == batch.NodeBatches[ 0 ].VertexCount ) ); // // batches.Add( batch ); // // batchVertexBaseIndex += batchVertexCount; // //} // //var materialIndex = mesh.MaterialIndex; // //var triangles = new Triangle[mesh.TriangleCount]; // //for ( var i = 0; i < mesh.Triangles.Length; i++ ) // //{ // // ref var triangle = ref triangles[i]; // // triangle.A = ( ushort )vertexIndexRemap[mesh.Triangles[i].A]; // // triangle.B = ( ushort )vertexIndexRemap[mesh.Triangles[i].B]; // // triangle.C = ( ushort )vertexIndexRemap[mesh.Triangles[i].C]; // //} // //mesh = new MeshType7(); // //mesh.Batches.AddRange( batches ); // //mesh.Triangles = triangles; // //mesh.MaterialIndex = materialIndex; // //node.Geometry.Meshes[meshIndex] = mesh; // writer.WriteLine( $"o node_{node.Name}_mesh_{meshIndex}" ); // foreach ( var triangle in mesh.Triangles ) // { // writer.WriteLine( "f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}", vertexBaseIndex + triangle.A + 1, vertexBaseIndex + triangle.B + 1, vertexBaseIndex + triangle.C + 1 ); // } // vertexBaseIndex += mesh.VertexCount; // } // } // } //} //modelPack.Save( @"D:\Modding\DDS3\Nocturne\_HostRoot\dds3data\model\field\player_a.PB" ); //ReplaceModelTest(); //return; //GenerateMaterialPresets(); //return; //var modelPack = new ModelPack( @"..\..\..\..\Resources\player_a.PB" ); //foreach ( var material in modelPack.Models[0].Materials ) //{ // Console.WriteLine( MaterialPresetStore.GetPresetId( material ) ); //} //return; ////for ( var i = 0; i < modelPack.TexturePack.Count; i++ ) ////{ //// var texture = modelPack.TexturePack[ i ]; //// texture.GetBitmap().Save( $"player_a_{i}.png" ); ////} //modelPack.Save( @"D:\Modding\DDS3\Nocturne\_HostRoot\dds3data\model\field\player_a.PB" ); ////ReplaceModelTest(); //OpenAndSaveModelPackBatchTest(); }
public ModelPackDrawable(ModelPack model, MaterialTextureCreator textureCreator) { Model = new GLModel(model, textureCreator); }
public ModelPackDrawable(ModelPack model) { ModelPack = model; Model = new GLModel(model, (material, textureName) => new GLTexture(model.Textures[textureName])); }
public void ToScene(Scene currentScene, MainCaches caches) { foreach (var obj in objects) { GameObject gameObject = GetGameObject(obj); if (obj.type == "mmdModel") { string pmxPath = obj.path; ModelPack modelPack = caches.GetModel(pmxPath); gameObject.LoadPmx(modelPack); var renderer = gameObject.GetComponent <MMDRendererComponent>(); var animationState = gameObject.GetComponent <AnimationStateComponent>(); if (obj.skinning != null) { renderer.skinning = (bool)obj.skinning; } if (obj.enableIK != null) { renderer.enableIK = (bool)obj.enableIK; } if (obj.properties != null) { if (obj.properties.TryGetValue("motion", out string motion)) { animationState.motionPath = motion; } } if (obj.materials != null) { Mat2Mat(obj.materials, renderer.Materials); } currentScene.AddGameObject(gameObject); } else if (obj.type == "model") { string path = obj.path; ModelPack modelPack = caches.GetModel(path); modelPack.LoadMeshComponent(gameObject); var renderer = gameObject.GetComponent <MeshRendererComponent>(); if (obj.materials != null) { Mat2Mat(obj.materials, renderer.Materials); } currentScene.AddGameObject(gameObject); } else { Caprice.Display.UIShowType uiShowType = default; switch (obj.type) { case "lighting": uiShowType = Caprice.Display.UIShowType.Light; break; case "decal": uiShowType = Caprice.Display.UIShowType.Decal; break; case "particle": uiShowType = Caprice.Display.UIShowType.Particle; break; default: continue; } VisualComponent component = new VisualComponent(); component.UIShowType = uiShowType; gameObject.AddComponent(component); if (obj.visual != null) { component.material = Mat2Mat(obj.visual.material); } currentScene.AddGameObject(gameObject); } } }
public static void ReloadModel(this MMDRendererComponent rendererComponent, ModelPack modelPack) { rendererComponent.Materials.Clear(); rendererComponent.materialsBaseData.Clear(); rendererComponent.computedMaterialsData.Clear(); rendererComponent.mesh = modelPack.GetMesh(); rendererComponent.meshPosData = modelPack.verticesDataPosPart; rendererComponent.meshVertexCount = rendererComponent.mesh.m_vertexCount; rendererComponent.meshIndexCount = rendererComponent.mesh.m_indexCount; //rendererComponent.meshParticleBuffer = new TwinBuffer(); //rendererComponent.meshParticleBuffer.Reload(rendererComponent.mesh.m_vertexCount * 32); rendererComponent.meshPosData1 = new Vector3[rendererComponent.mesh.m_vertexCount]; rendererComponent.meshPosData2 = new Vector3[rendererComponent.mesh.m_vertexCount]; rendererComponent.meshAppend.Reload(rendererComponent.meshVertexCount); var modelResource = modelPack.pmx; for (int i = 0; i < modelResource.Materials.Count; i++) { var mmdMat = modelResource.Materials[i]; RuntimeMaterial mat = new RuntimeMaterial { Name = mmdMat.Name, NameEN = mmdMat.NameEN, texIndex = mmdMat.TextureIndex, indexCount = mmdMat.TriangeIndexNum, innerStruct = { DiffuseColor = mmdMat.DiffuseColor, SpecularColor = mmdMat.SpecularColor, EdgeSize = mmdMat.EdgeScale, EdgeColor = mmdMat.EdgeColor, AmbientColor = new Vector3(MathF.Pow(mmdMat.AmbientColor.X, 2.2f), MathF.Pow(mmdMat.AmbientColor.Y, 2.2f), MathF.Pow(mmdMat.AmbientColor.Z, 2.2f)), Roughness = 0.5f, Specular = 0.5f, }, DrawFlags = (DrawFlag)mmdMat.DrawFlags, toonIndex = mmdMat.ToonIndex, }; rendererComponent.Materials.Add(mat); rendererComponent.materialsBaseData.Add(mat.innerStruct); rendererComponent.computedMaterialsData.Add(mat.innerStruct); } int morphCount = modelResource.Morphs.Count; rendererComponent.vertexMorphsA = new List <MorphVertexDesc[]>(); rendererComponent.vertexMorphsB = new List <MorphVertexDesc[]>(); for (int i = 0; i < morphCount; i++) { if (modelResource.Morphs[i].Type == PMX_MorphType.Vertex) { MorphVertexDesc[] morphVertexStructs = new MorphVertexDesc[modelResource.Morphs[i].MorphVertexs.Length]; PMX_MorphVertexDesc[] sourceMorph = modelResource.Morphs[i].MorphVertexs; for (int j = 0; j < morphVertexStructs.Length; j++) { morphVertexStructs[j].VertexIndex = sourceMorph[j].VertexIndex; } rendererComponent.vertexMorphsA.Add(morphVertexStructs); rendererComponent.vertexMorphsB.Add(morphVertexStructs); } else { rendererComponent.vertexMorphsA.Add(null); rendererComponent.vertexMorphsB.Add(null); } } //Dictionary<int, int> reportFrequency = new Dictionary<int, int>(10000); //for (int i = 0; i < morphCount; i++) //{ // if (modelResource.Morphs[i].Type == PMX_MorphType.Vertex) // { // PMX_MorphVertexDesc[] sourceMorph = modelResource.Morphs[i].MorphVertexs; // for (int j = 0; j < sourceMorph.Length; j++) // { // if (!reportFrequency.TryAdd(sourceMorph[j].VertexIndex, 1)) // { // reportFrequency[sourceMorph[j].VertexIndex]++; // } // } // } //} //int[] freqResult = new int[32]; //foreach (int value1 in reportFrequency.Values) //{ // if (value1 < 32) // { // freqResult[value1]++; // } // else // { // } //} }
static void ConvertFile(string filename) { string basepath = Path.GetDirectoryName(filename); string name = Path.GetFileNameWithoutExtension(filename); string ext = Path.GetExtension(filename).ToLower(); switch (ext) { case ".lev": { Scene scn = Scene.FromFile(filename); //scn.quads = scn.quads.OrderBy(o => o.id).ToList(); scn.Export(basepath, ExportFlags.All); break; } case ".ctr": case ".dyn": { CtrModel d = CtrModel.FromFile(filename); d.Export(basepath); break; } case ".obj": { OBJ obj = OBJ.FromFile(filename); CtrModel ctr = CtrModel.FromObj(obj); ctr.Save(basepath); break; } case ".ply": { CtrModel ctr = CtrModel.FromPly(filename); ctr.Save(basepath); break; } case ".mpk": { string vrampath = Path.ChangeExtension(filename, "vrm"); if (!File.Exists(vrampath)) { vrampath = Path.Combine(Path.GetDirectoryName(filename), "shared.vrm"); if (!File.Exists(vrampath)) { Console.WriteLine("Warning! No vram file found.\r\nPlease put shared.vrm file with mpk you want to extract."); vrampath = ""; } } ModelPack mpk = ModelPack.FromFile(filename); mpk.Extract(Path.Combine(basepath, name), CtrVrm.FromFile(vrampath).GetVram()); break; } default: { Console.WriteLine($"Unsupported file: {filename}"); return; } } Console.WriteLine("Done!"); }
public static void ReloadModels(Scene scene, MainCaches mainCaches, ProcessingList processingList, GameDriverContext gameDriverContext) { if (mainCaches.modelTaskLocker.GetLocker()) { Task.Run(async() => { List <ModelPack> packs = new List <ModelPack>(); lock (mainCaches.ModelPackCaches) foreach (var modelPack in mainCaches.ModelPackCaches.Values) { if (modelPack.Status == GraphicsObjectStatus.loaded || modelPack.Status == GraphicsObjectStatus.error) { packs.Add(modelPack); } } List <ModelPack> updatePacks = new List <ModelPack>(); for (int i = 0; i < packs.Count; i++) { var pack = packs[i]; if (pack.LoadTask == null) { try { var file = await pack.folder.GetFileAsync(pack.relativePath); var attr = await file.GetBasicPropertiesAsync(); if (attr.DateModified != pack.lastModifiedTime) { updatePacks.Add(pack); pack.lastModifiedTime = attr.DateModified; } } catch { } } } List <ModelPack> newPacks = new List <ModelPack>(); for (int i = 0; i < updatePacks.Count; i++) { var file = await updatePacks[i].folder.GetFileAsync(updatePacks[i].relativePath); ModelPack pack = new ModelPack(); pack.LoadTask = LoadPMX(file, updatePacks[i].folder, pack, processingList); newPacks.Add(pack); } for (int i = 0; i < newPacks.Count; i++) { var pack = newPacks[i]; void fun1() { lock (mainCaches.ModelPackCaches) { mainCaches.ModelPackCaches[pack.fullPath] = pack; } for (int j = 0; j < scene.Entities.Count; j++) { if (scene.Entities[j].ModelPath == pack.fullPath) { scene.Entities[j].ReloadModel(processingList, pack, GetTextureList(processingList, mainCaches, pack.folder, pack.pmx)); scene.EntityRefreshList.Add(scene.Entities[j]); gameDriverContext.RequireResetPhysics = true; gameDriverContext.RequireRender(true); mainCaches.ReloadTextures(processingList, gameDriverContext.RequireRender); } } } if (pack.LoadTask == null && pack.Status == GraphicsObjectStatus.loaded) { fun1(); } else { try { pack.LoadTask.Wait(); fun1(); } catch { } } } mainCaches.modelTaskLocker.FreeLocker(); }).Wait(); } }