Extract model loading functionality out
This commit is contained in:
		
							parent
							
								
									e313ca58a7
								
							
						
					
					
						commit
						b6a65fc10b
					
				| 
						 | 
					@ -164,25 +164,20 @@ public partial class Mission : Node3D
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// Let's try and place an object :)
 | 
								// Let's try and place an object :)
 | 
				
			||||||
			var modelName = modelNameProp.modelName + ".bin";
 | 
								var modelName = modelNameProp.modelName + ".bin";
 | 
				
			||||||
			var objPath = _installPaths.GetObjectPath(_campaignName, modelName);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var pos = brush.position.ToGodotVec3();
 | 
								var pos = brush.position.ToGodotVec3();
 | 
				
			||||||
			var rawRot = brush.angle;
 | 
								var rawRot = brush.angle;
 | 
				
			||||||
			var rot = new Vector3(rawRot.Y, rawRot.Z, rawRot.X) * 360 / ushort.MaxValue;
 | 
								var rot = new Vector3(rawRot.Y, rawRot.Z, rawRot.X) * 360 / ushort.MaxValue;
 | 
				
			||||||
			var scale = scaleProp == null ? Vector3.One : scaleProp.scale.ToGodotVec3(false);
 | 
								var scale = scaleProp == null ? Vector3.One : scaleProp.scale.ToGodotVec3(false);
 | 
				
			||||||
			var model = new Model
 | 
								var model = ModelLoader.LoadModel(_installPaths, _campaignName, modelName);
 | 
				
			||||||
 | 
								if (model != null)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Position = pos,
 | 
									model.Position = pos;
 | 
				
			||||||
				RotationDegrees = rot,
 | 
									model.RotationDegrees = rot;
 | 
				
			||||||
				Scale = scale,
 | 
									model.Scale = scale;
 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
			if (objPath != null)
 | 
					 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				model.BuildModel("", objPath);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
				AddChild(model);
 | 
									AddChild(model);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private void BuildWrMeshes(WorldRep worldRep)
 | 
						private void BuildWrMeshes(WorldRep worldRep)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,107 @@
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using Godot;
 | 
				
			||||||
 | 
					using KeepersCompound.LGS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace KeepersCompound.TMV;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public static class ModelLoader
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public static MeshInstance3D LoadModel(ResourcePathManager pathManager, string campaignName, string modelName)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        var modelPath = pathManager.GetObjectPath(campaignName, modelName);
 | 
				
			||||||
 | 
					        if (modelPath == null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        var modelFile = new ModelFile(modelPath);
 | 
				
			||||||
 | 
					        if (modelFile == null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            GD.Print($"Failed to load model file: {modelPath}");
 | 
				
			||||||
 | 
					            return null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // TODO: Remove this disgusting hack. Not only is it a hack, it doesn't support custom models
 | 
				
			||||||
 | 
					        var baseDir = Path.GetDirectoryName(modelPath);
 | 
				
			||||||
 | 
					        var options = new EnumerationOptions
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            MatchCasing = MatchCasing.CaseInsensitive,
 | 
				
			||||||
 | 
					            RecurseSubdirectories = true,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        var materials = new List<StandardMaterial3D>();
 | 
				
			||||||
 | 
					        foreach (var material in modelFile.Materials)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (material.Type == 0)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var paths = Directory.GetFiles(baseDir, material.Name, options);
 | 
				
			||||||
 | 
					                if (paths.IsEmpty()) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                materials.Add(new StandardMaterial3D
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    AlbedoTexture = TextureLoader.LoadTexture(paths[0])
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var b = (material.Handle) & 0xff;
 | 
				
			||||||
 | 
					                var g = (material.Handle >> 8) & 0xff;
 | 
				
			||||||
 | 
					                var r = (material.Handle >> 16) & 0xff;
 | 
				
			||||||
 | 
					                var colour = new Color(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
 | 
				
			||||||
 | 
					                materials.Add(new StandardMaterial3D
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    AlbedoColor = colour
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var surfaceDataMap = new Dictionary<int, MeshSurfaceData>();
 | 
				
			||||||
 | 
					        foreach (var poly in modelFile.Polygons)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var vertices = new List<Vector3>();
 | 
				
			||||||
 | 
					            var normal = modelFile.Normals[poly.Normal].ToGodotVec3();
 | 
				
			||||||
 | 
					            var uvs = new List<Vector2>();
 | 
				
			||||||
 | 
					            for (var i = 0; i < poly.VertexCount; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var vertex = modelFile.Vertices[poly.VertexIndices[i]];
 | 
				
			||||||
 | 
					                vertices.Add(vertex.ToGodotVec3());
 | 
				
			||||||
 | 
					                if (i < poly.UvIndices.Length)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var uv = modelFile.Uvs[poly.UvIndices[i]];
 | 
				
			||||||
 | 
					                    uvs.Add(new Vector2(uv.X, uv.Y));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    uvs.Add(Vector2.Zero);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (!surfaceDataMap.ContainsKey(poly.Data))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                surfaceDataMap.Add(poly.Data, new MeshSurfaceData());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            surfaceDataMap[poly.Data].AddPolygon(vertices, normal, uvs, uvs);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var mesh = new ArrayMesh();
 | 
				
			||||||
 | 
					        foreach (var (materialId, surfaceData) in surfaceDataMap)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var array = surfaceData.BuildSurfaceArray();
 | 
				
			||||||
 | 
					            var surfaceIdx = mesh.GetSurfaceCount();
 | 
				
			||||||
 | 
					            mesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, array);
 | 
				
			||||||
 | 
					            for (var i = 0; i < materials.Count; i++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var m = modelFile.Materials[i];
 | 
				
			||||||
 | 
					                if (m.Slot == materialId)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    mesh.SurfaceSetMaterial(surfaceIdx, materials[i]);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var pos = -modelFile.Header.Center.ToGodotVec3();
 | 
				
			||||||
 | 
					        var meshInstance = new MeshInstance3D { Mesh = mesh, Position = pos };
 | 
				
			||||||
 | 
					        return meshInstance;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue