private void SetupDrillSensor(VRageMath.Matrix fromReference, int id, VRageMath.BoundingBox bb) { // grid size in meters per block float gridSize = sensors[id].CubeGrid.GridSize; // matrix from grid coordinate system to sensor coordinate system VRageMath.Matrix toSensor = new VRageMath.Matrix(); sensors[id].Orientation.GetMatrix(out toSensor); // matrix is orthogonal => transposed matrix = inversed matrix VRageMath.Matrix.Transpose(ref toSensor, out toSensor); VRageMath.Vector3[] corners = bb.GetCorners(); VRageMath.Vector3 diffMax = corners[1] - sensors[id].Position; VRageMath.Vector3 diffMin = corners[7] - sensors[id].Position; List <VRageMath.Vector3> .Enumerator enumerator = XUtils.Directions.GetEnumerator(); while (enumerator.MoveNext()) { VRageMath.Vector3 dir = enumerator.Current; VRageMath.Vector3 gridDir = VRageMath.Vector3.Transform(dir, fromReference); float lengthToMax = (diffMax * gridDir).Max(); float lengthToMin = (diffMin * gridDir).Max(); float offset = Sensors.getOffset(VRageMath.Vector3.Transform(gridDir, toSensor)); float value = _astroidDetectSize + (Math.Max(lengthToMax, lengthToMin) + offset) * gridSize; value = Math.Max(Math.Min(value, sensors.Max), sensors.Min); sensors.Extend(dir, id, value); } }
public void GetTriangleBoundingBox(int triangleIndex, ref BoundingBox boundingBox) { boundingBox = BoundingBox.CreateInvalid(); Vector3 v1, v2, v3; GetVertex(Triangles[triangleIndex].I0, Triangles[triangleIndex].I1, Triangles[triangleIndex].I2, out v1, out v2, out v3); boundingBox.Include( v1, v2, v3); }
public Line(Vector3 from, Vector3 to, bool calculateBoundingBox = true) { this.From = from; this.To = to; this.Direction = to - from; this.Length = this.Direction.Normalize(); this.BoundingBox = VRageMath.BoundingBox.CreateInvalid(); if (calculateBoundingBox) { this.BoundingBox = this.BoundingBox.Include(ref from); this.BoundingBox = this.BoundingBox.Include(ref to); } }
private void SetupSensors() { if (sensors == null) { throw new Exception("No sensors available (sensors == null)."); } VRageMath.BoundingBox bb = GetBounds(); VRageMath.Matrix fromReference = new VRageMath.Matrix(); ReferenceBlock.Orientation.GetMatrix(out fromReference); //VRageMath.Vector3 v = m.Forward.Min() < 0 ? -m.Forward * bb.Min + (XUtils.One + m.Forward) * bb.Max : (XUtils.One - m.Forward) * bb.Min + m.Forward * bb.Max; _sensorIds.Clear(); // Asteroid search laser int id = sensors.GetClosestSensor(bb.Center, _sensorIds); if (id == sensors.CountSensors) { throw new Exception("Not enough sensors."); } _sensorIds.Add(id); var sensor = sensors[id]; sensors.ExtendFront(id, sensors.Max); sensors.ExtendBack(id, sensors.Min); sensors.ExtendBottom(id, sensors.Min); sensors.ExtendLeft(id, sensors.Min); sensors.ExtendRight(id, sensors.Min); sensors.ExtendTop(id, sensors.Min); Sensors.SetFlags(sensor, Sensors.Action.DetectAsteroids.Value); sensor.GetActionWithName("OnOff_On").Apply(sensor); sensor.RequestShowOnHUD(true); sensor.SetCustomName(sensor.DefinitionDisplayNameText + " X Laser"); // Asteroid collision detector id = sensors.GetClosestSensor(bb.Center, _sensorIds); if (id == sensors.CountSensors) { throw new Exception("Not enough sensors."); } _sensorIds.Add(id); sensor = sensors[id]; SetupDrillSensor(fromReference, id, bb); Sensors.SetFlags(sensor, Sensors.Action.DetectAsteroids.Value); sensor.GetActionWithName("OnOff_On").Apply(sensors[id]); sensor.RequestShowOnHUD(true); sensor.SetCustomName(sensor.DefinitionDisplayNameText + " X Drill"); }
void IPrimitiveManagerBase.GetPrimitiveBox(int prim_index, out AABB primbox) { BoundingBox bbox = BoundingBox.CreateInvalid(); Vector3 v1 = GetVertex(Triangles[prim_index].I0); Vector3 v2 = GetVertex(Triangles[prim_index].I1); Vector3 v3 = GetVertex(Triangles[prim_index].I2); bbox.Include( ref v1, ref v2, ref v3); primbox = new AABB() { m_min = bbox.Min.ToBullet(), m_max = bbox.Max.ToBullet() }; }
internal void AddBoundingBox(BoundingBox bb, Color color) { var v0 = bb.Center - bb.HalfExtents; var v1 = v0 + new Vector3(bb.HalfExtents.X * 2, 0, 0); var v2 = v0 + new Vector3(bb.HalfExtents.X * 2, bb.HalfExtents.Y * 2, 0); var v3 = v0 + new Vector3(0, bb.HalfExtents.Y * 2, 0); var v4 = v0 + new Vector3(0, 0, bb.HalfExtents.Z * 2); var v5 = v4 + new Vector3(bb.HalfExtents.X * 2, 0, 0); var v6 = v4 + new Vector3(bb.HalfExtents.X * 2, bb.HalfExtents.Y * 2, 0); var v7 = v4 + new Vector3(0, bb.HalfExtents.Y * 2, 0); var bcolor = new Byte4(color.R, color.G, color.B, color.A); Add(new MyVertexFormatPositionColor(v0, bcolor)); Add(new MyVertexFormatPositionColor(v1, bcolor)); Add(new MyVertexFormatPositionColor(v1, bcolor)); Add(new MyVertexFormatPositionColor(v2, bcolor)); Add(new MyVertexFormatPositionColor(v2, bcolor)); Add(new MyVertexFormatPositionColor(v3, bcolor)); Add(new MyVertexFormatPositionColor(v0, bcolor)); Add(new MyVertexFormatPositionColor(v3, bcolor)); Add(new MyVertexFormatPositionColor(v4, bcolor)); Add(new MyVertexFormatPositionColor(v5, bcolor)); Add(new MyVertexFormatPositionColor(v5, bcolor)); Add(new MyVertexFormatPositionColor(v6, bcolor)); Add(new MyVertexFormatPositionColor(v6, bcolor)); Add(new MyVertexFormatPositionColor(v7, bcolor)); Add(new MyVertexFormatPositionColor(v4, bcolor)); Add(new MyVertexFormatPositionColor(v7, bcolor)); Add(new MyVertexFormatPositionColor(v0, bcolor)); Add(new MyVertexFormatPositionColor(v4, bcolor)); Add(new MyVertexFormatPositionColor(v1, bcolor)); Add(new MyVertexFormatPositionColor(v5, bcolor)); Add(new MyVertexFormatPositionColor(v2, bcolor)); Add(new MyVertexFormatPositionColor(v6, bcolor)); Add(new MyVertexFormatPositionColor(v3, bcolor)); Add(new MyVertexFormatPositionColor(v7, bcolor)); }
public void LoadAnimationData() { if (m_loadedData) return; lock (this) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyModel::LoadAnimationData"); MyLog.Default.WriteLine("MyModel.LoadData -> START", LoggingOptions.LOADING_MODELS); MyLog.Default.IncreaseIndent(LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("m_assetName: " + m_assetName, LoggingOptions.LOADING_MODELS); // Read data from model TAG parameter. There are stored vertex positions, triangle indices, vectors, ... everything we need. VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - import data"); MyLog.Default.WriteLine(String.Format("Importing asset {0}, path: {1}", m_assetName, AssetName), LoggingOptions.LOADING_MODELS); try { m_importer.ImportData(AssetName); } catch { MyLog.Default.WriteLine(String.Format("Importing asset failed {0}", m_assetName)); throw; } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - load tag data"); Dictionary<string, object> tagData = m_importer.GetTagData(); Debug.Assert(tagData.Count != 0, String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName)); if (tagData.Count != 0) { DataVersion = m_importer.DataVersion; Animations = (ModelAnimations)tagData[MyImporterConstants.TAG_ANIMATIONS]; Bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES]; BoundingBox = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX]; BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE]; BoundingBoxSize = BoundingBox.Max - BoundingBox.Min; BoundingBoxSizeHalf = BoundingBoxSize / 2.0f; Dummies = tagData[MyImporterConstants.TAG_DUMMIES] as Dictionary<string, MyModelDummy>; BoneMapping = tagData[MyImporterConstants.TAG_BONE_MAPPING] as VRageMath.Vector3I[]; if (BoneMapping.Length == 0) BoneMapping = null; } else { DataVersion = 0; Animations = null; Bones = null; BoundingBox = default(BoundingBox); BoundingSphere = default(BoundingSphere); BoundingBoxSize = default(Vector3); BoundingBoxSizeHalf = default(Vector3); Dummies = null; BoneMapping = null; } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize); if (tagData.Count != 0) m_loadedData = true; MyLog.Default.DecreaseIndent(LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("MyModel.LoadAnimationData -> END", LoggingOptions.LOADING_MODELS); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } }
// Sort of lazy-load, where constructor just saves information about what this model should be, but real load is done here - and only one time. // This loads only vertex data, doesn't touch GPU // Can be called from main and background thread public void LoadData() { if (m_loadedData) return; lock (this) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyModel::LoadData"); MyLog.Default.WriteLine("MyModel.LoadData -> START", LoggingOptions.LOADING_MODELS); MyLog.Default.IncreaseIndent(LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("m_assetName: " + m_assetName, LoggingOptions.LOADING_MODELS); // Read data from model TAG parameter. There are stored vertex positions, triangle indices, vectors, ... everything we need. VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - import data"); MyLog.Default.WriteLine(String.Format("Importing asset {0}, path: {1}", m_assetName, AssetName), LoggingOptions.LOADING_MODELS); string assetForImport = AssetName; var fsPath = Path.IsPathRooted(AssetName) ? AssetName : Path.Combine(MyFileSystem.ContentPath, AssetName); if (!MyFileSystem.FileExists(fsPath)) { assetForImport = @"Models\Debug\Error.mwm"; } try { m_importer.ImportData(assetForImport); } catch { MyLog.Default.WriteLine(String.Format("Importing asset failed {0}", m_assetName)); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); throw; } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); DataVersion = m_importer.DataVersion; VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - load tag data"); Dictionary<string, object> tagData = m_importer.GetTagData(); if (tagData.Count == 0) { VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); throw new Exception(String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName)); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - vertex, normals, texture coords"); HalfVector4[] vertices = (HalfVector4[])tagData[MyImporterConstants.TAG_VERTICES]; System.Diagnostics.Debug.Assert(vertices.Length > 0); Byte4[] normals = (Byte4[])tagData[MyImporterConstants.TAG_NORMALS]; m_vertices = new MyCompressedVertexNormal[vertices.Length]; if (normals.Length > 0) { for (int v = 0; v < vertices.Length; v++) { m_vertices[v] = new MyCompressedVertexNormal() { Position = vertices[v],// VF_Packer.PackPosition(ref vertices[v]), Normal = normals[v]//VF_Packer.PackNormalB4(ref normals[v]) }; } } else { for (int v = 0; v < vertices.Length; v++) { m_vertices[v] = new MyCompressedVertexNormal() { Position = vertices[v],// VF_Packer.PackPosition(ref vertices[v]), }; } } m_verticesCount = vertices.Length; VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - mesh"); var materials = new Dictionary<string, MyMeshMaterial>(); m_meshContainer.Clear(); if (tagData.ContainsKey(MyImporterConstants.TAG_MESH_PARTS)) { List<int> indices = new List<int>(GetVerticesCount()); // Default capacity estimation int maxIndex = 0; List<MyMeshPartInfo> meshParts = tagData[MyImporterConstants.TAG_MESH_PARTS] as List<MyMeshPartInfo>; foreach (MyMeshPartInfo meshPart in meshParts) { MyMesh mesh = new MyMesh(meshPart, m_assetName); mesh.IndexStart = indices.Count; mesh.TriCount = meshPart.m_indices.Count / 3; if (mesh.Material.Name != null) materials.Add(mesh.Material.Name, mesh.Material); if (m_loadUV && false == m_hasUV) { m_texCoords = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0]; m_hasUV = true; m_loadUV = false; } if (meshPart.m_MaterialDesc != null && meshPart.Technique == MyMeshDrawTechnique.GLASS) { GlassData = mesh; HalfVector2[] forLoadingTexCoords0 = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0]; List<HalfVector2> neededTexCoords = new List<HalfVector2>(); for (int t = 0; t < meshPart.m_indices.Count; t++) { int index = meshPart.m_indices[t]; neededTexCoords.Add(forLoadingTexCoords0[index]); } GlassTexCoords = neededTexCoords.ToArray(); } System.Diagnostics.Debug.Assert(mesh.TriCount > 0); if (mesh.TriCount == 0) { VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); return; } foreach (var i in meshPart.m_indices) { indices.Add(i); if (i > maxIndex) { maxIndex = i; } } m_meshContainer.Add(mesh); } if (maxIndex <= ushort.MaxValue) { // create 16 bit indices m_Indices_16bit = new ushort[indices.Count]; for (int i = 0; i < indices.Count; i++) { m_Indices_16bit[i] = (ushort)indices[i]; } } else { // use 32bit indices m_Indices = indices.ToArray(); } } m_meshSections.Clear(); if (tagData.ContainsKey(MyImporterConstants.TAG_MESH_SECTIONS)) { List<MyMeshSectionInfo> sections = tagData[MyImporterConstants.TAG_MESH_SECTIONS] as List<MyMeshSectionInfo>; int sectionindex = 0; foreach (MyMeshSectionInfo sectinfo in sections) { MyMeshSection section = new MyMeshSection() { Name = sectinfo.Name, Index = sectionindex }; m_meshSections.Add(section.Name, section); sectionindex++; } } if (tagData.ContainsKey(MyImporterConstants.TAG_MODEL_BVH)) { m_bvh = new MyQuantizedBvhAdapter(tagData[MyImporterConstants.TAG_MODEL_BVH] as GImpactQuantizedBvh, this); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - other data"); Animations = (ModelAnimations)tagData[MyImporterConstants.TAG_ANIMATIONS]; Bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES]; BoundingBox = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX]; BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE]; BoundingBoxSize = BoundingBox.Max - BoundingBox.Min; BoundingBoxSizeHalf = BoundingBoxSize / 2.0f; Dummies = tagData[MyImporterConstants.TAG_DUMMIES] as Dictionary<string, MyModelDummy>; BoneMapping = tagData[MyImporterConstants.TAG_BONE_MAPPING] as VRageMath.Vector3I[]; if (tagData.ContainsKey(MyImporterConstants.TAG_MODEL_FRACTURES)) ModelFractures = (MyModelFractures)tagData[MyImporterConstants.TAG_MODEL_FRACTURES]; object patternScale; if (tagData.TryGetValue(MyImporterConstants.TAG_PATTERN_SCALE, out patternScale)) { PatternScale = (float)patternScale; } if (BoneMapping.Length == 0) BoneMapping = null; if (tagData.ContainsKey(MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY)) { HavokData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY]; byte[] tagCollisionData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY]; if (tagCollisionData.Length > 0 && HkBaseSystem.IsThreadInitialized) { bool containsSceneData; bool containsDestructionData; List<HkShape> shapesList = new List<HkShape>(); if (!HkShapeLoader.LoadShapesListFromBuffer(tagCollisionData, shapesList, out containsSceneData, out containsDestructionData)) { MyLog.Default.WriteLine(string.Format("Model {0} - Unable to load collision geometry", AssetName), LoggingOptions.LOADING_MODELS); //Debug.Fail("Collision model was exported in wrong way: " + m_assetName); } if (shapesList.Count > 10) MyLog.Default.WriteLine(string.Format("Model {0} - Found too many collision shapes, only the first 10 will be used", AssetName), LoggingOptions.LOADING_MODELS); if (HavokCollisionShapes != null) { Debug.Fail("Shapes already loaded"); } if (shapesList.Count > 0) { HavokCollisionShapes = shapesList.ToArray(); } else { MyLog.Default.WriteLine(string.Format("Model {0} - Unable to load collision geometry from file, default collision will be used !", AssetName)); } if (containsDestructionData) HavokDestructionData = tagCollisionData; ExportedWrong = !containsSceneData; } } if (tagData.ContainsKey(MyImporterConstants.TAG_HAVOK_DESTRUCTION)) { if (((byte[])tagData[MyImporterConstants.TAG_HAVOK_DESTRUCTION]).Length > 0) HavokDestructionData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_DESTRUCTION]; } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - copy triangle indices"); // Prepare data CopyTriangleIndices(); m_trianglesCount = Triangles.Length; // Remember this numbers as list may be cleared at the end of this method VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); MyLog.Default.WriteLine("Triangles.Length: " + Triangles.Length, LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("Vertexes.Length: " + GetVerticesCount(), LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("Centered: " + (bool)tagData[MyImporterConstants.TAG_CENTERED], LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("UseChannelTextures: " + (bool)tagData[MyImporterConstants.TAG_USE_CHANNEL_TEXTURES], LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("Length in meters: " + (float)tagData[MyImporterConstants.TAG_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("Rescale to length in meters?: " + (bool)tagData[MyImporterConstants.TAG_RESCALE_TO_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("BoundingBox: " + BoundingBox, LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("BoundingSphere: " + BoundingSphere, LoggingOptions.LOADING_MODELS); VRage.Utils.Stats.PerAppLifetime.MyModelsCount++; VRage.Utils.Stats.PerAppLifetime.MyModelsMeshesCount += m_meshContainer.Count; VRage.Utils.Stats.PerAppLifetime.MyModelsVertexesCount += GetVerticesCount(); VRage.Utils.Stats.PerAppLifetime.MyModelsTrianglesCount += Triangles.Length; ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize); m_loadedData = true; m_loadingErrorProcessed = false; MyLog.Default.DecreaseIndent(LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("MyModel.LoadData -> END", LoggingOptions.LOADING_MODELS); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } }
void IMyEntities.GetInflatedPlayerBoundingBox(ref VRageMath.BoundingBox playerBox, float inflation) { MyEntities.GetInflatedPlayerBoundingBox(ref playerBox, inflation); }
public void LoadAnimationData() { if (m_loadedData) { return; } lock (this) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyModel::LoadAnimationData"); MyLog.Default.WriteLine("MyModel.LoadData -> START", LoggingOptions.LOADING_MODELS); MyLog.Default.IncreaseIndent(LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("m_assetName: " + m_assetName, LoggingOptions.LOADING_MODELS); // Read data from model TAG parameter. There are stored vertex positions, triangle indices, vectors, ... everything we need. VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - import data"); MyLog.Default.WriteLine(String.Format("Importing asset {0}, path: {1}", m_assetName, AssetName), LoggingOptions.LOADING_MODELS); try { m_importer.ImportData(AssetName); } catch { MyLog.Default.WriteLine(String.Format("Importing asset failed {0}", m_assetName)); throw; } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - load tag data"); Dictionary <string, object> tagData = m_importer.GetTagData(); //Debug.Assert(tagData.Count != 0, String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName)); if (tagData.Count != 0) { DataVersion = m_importer.DataVersion; Animations = (ModelAnimations)tagData[MyImporterConstants.TAG_ANIMATIONS]; Bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES]; BoundingBox = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX]; BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE]; BoundingBoxSize = BoundingBox.Max - BoundingBox.Min; BoundingBoxSizeHalf = BoundingBoxSize / 2.0f; Dummies = tagData[MyImporterConstants.TAG_DUMMIES] as Dictionary <string, MyModelDummy>; BoneMapping = tagData[MyImporterConstants.TAG_BONE_MAPPING] as VRageMath.Vector3I[]; if (BoneMapping.Length == 0) { BoneMapping = null; } } else { DataVersion = 0; Animations = null; Bones = null; BoundingBox = default(BoundingBox); BoundingSphere = default(BoundingSphere); BoundingBoxSize = default(Vector3); BoundingBoxSizeHalf = default(Vector3); Dummies = null; BoneMapping = null; } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize); if (tagData.Count != 0) { m_loadedData = true; } MyLog.Default.DecreaseIndent(LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("MyModel.LoadAnimationData -> END", LoggingOptions.LOADING_MODELS); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } }
// Sort of lazy-load, where constructor just saves information about what this model should be, but real load is done here - and only one time. // This loads only vertex data, doesn't touch GPU // Can be called from main and background thread public void LoadData() { if (m_loadedData) { return; } lock (this) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyModel::LoadData"); MyLog.Default.WriteLine("MyModel.LoadData -> START", LoggingOptions.LOADING_MODELS); MyLog.Default.IncreaseIndent(LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("m_assetName: " + m_assetName, LoggingOptions.LOADING_MODELS); // Read data from model TAG parameter. There are stored vertex positions, triangle indices, vectors, ... everything we need. VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - import data"); MyLog.Default.WriteLine(String.Format("Importing asset {0}, path: {1}", m_assetName, AssetName), LoggingOptions.LOADING_MODELS); string assetForImport = AssetName; var fsPath = Path.IsPathRooted(AssetName) ? AssetName : Path.Combine(MyFileSystem.ContentPath, AssetName); if (!MyFileSystem.FileExists(fsPath)) { assetForImport = @"Models\Debug\Error.mwm"; } try { m_importer.ImportData(assetForImport); } catch { MyLog.Default.WriteLine(String.Format("Importing asset failed {0}", m_assetName)); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); throw; } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); DataVersion = m_importer.DataVersion; VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - load tag data"); Dictionary <string, object> tagData = m_importer.GetTagData(); if (tagData.Count == 0) { VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); throw new Exception(String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName)); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - vertex, normals, texture coords"); HalfVector4[] vertices = (HalfVector4[])tagData[MyImporterConstants.TAG_VERTICES]; System.Diagnostics.Debug.Assert(vertices.Length > 0); Byte4[] normals = (Byte4[])tagData[MyImporterConstants.TAG_NORMALS]; m_vertices = new MyCompressedVertexNormal[vertices.Length]; if (normals.Length > 0) { for (int v = 0; v < vertices.Length; v++) { m_vertices[v] = new MyCompressedVertexNormal() { Position = vertices[v], // VF_Packer.PackPosition(ref vertices[v]), Normal = normals[v] //VF_Packer.PackNormalB4(ref normals[v]) }; } } else { for (int v = 0; v < vertices.Length; v++) { m_vertices[v] = new MyCompressedVertexNormal() { Position = vertices[v],// VF_Packer.PackPosition(ref vertices[v]), }; } } m_verticesCount = vertices.Length; VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - mesh"); var materials = new Dictionary <string, MyMeshMaterial>(); m_meshContainer.Clear(); if (tagData.ContainsKey(MyImporterConstants.TAG_MESH_PARTS)) { List <int> indices = new List <int>(GetVerticesCount()); // Default capacity estimation int maxIndex = 0; List <MyMeshPartInfo> meshParts = tagData[MyImporterConstants.TAG_MESH_PARTS] as List <MyMeshPartInfo>; foreach (MyMeshPartInfo meshPart in meshParts) { MyMesh mesh = new MyMesh(meshPart, m_assetName); mesh.IndexStart = indices.Count; mesh.TriCount = meshPart.m_indices.Count / 3; if (mesh.Material.Name != null) { materials.Add(mesh.Material.Name, mesh.Material); } if (m_loadUV && false == m_hasUV) { m_texCoords = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0]; m_hasUV = true; m_loadUV = false; } if (meshPart.m_MaterialDesc != null && meshPart.Technique == MyMeshDrawTechnique.GLASS) { GlassData = mesh; HalfVector2[] forLoadingTexCoords0 = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0]; List <HalfVector2> neededTexCoords = new List <HalfVector2>(); for (int t = 0; t < meshPart.m_indices.Count; t++) { int index = meshPart.m_indices[t]; neededTexCoords.Add(forLoadingTexCoords0[index]); } GlassTexCoords = neededTexCoords.ToArray(); } System.Diagnostics.Debug.Assert(mesh.TriCount > 0); if (mesh.TriCount == 0) { VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); return; } foreach (var i in meshPart.m_indices) { indices.Add(i); if (i > maxIndex) { maxIndex = i; } } m_meshContainer.Add(mesh); } if (maxIndex <= ushort.MaxValue) { // create 16 bit indices m_Indices_16bit = new ushort[indices.Count]; for (int i = 0; i < indices.Count; i++) { m_Indices_16bit[i] = (ushort)indices[i]; } } else { // use 32bit indices m_Indices = indices.ToArray(); } } m_meshSections.Clear(); if (tagData.ContainsKey(MyImporterConstants.TAG_MESH_SECTIONS)) { List <MyMeshSectionInfo> sections = tagData[MyImporterConstants.TAG_MESH_SECTIONS] as List <MyMeshSectionInfo>; int sectionindex = 0; foreach (MyMeshSectionInfo sectinfo in sections) { MyMeshSection section = new MyMeshSection() { Name = sectinfo.Name, Index = sectionindex }; m_meshSections.Add(section.Name, section); sectionindex++; } } if (tagData.ContainsKey(MyImporterConstants.TAG_MODEL_BVH)) { m_bvh = new MyQuantizedBvhAdapter(tagData[MyImporterConstants.TAG_MODEL_BVH] as GImpactQuantizedBvh, this); } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - other data"); Animations = (ModelAnimations)tagData[MyImporterConstants.TAG_ANIMATIONS]; Bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES]; BoundingBox = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX]; BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE]; BoundingBoxSize = BoundingBox.Max - BoundingBox.Min; BoundingBoxSizeHalf = BoundingBoxSize / 2.0f; Dummies = tagData[MyImporterConstants.TAG_DUMMIES] as Dictionary <string, MyModelDummy>; BoneMapping = tagData[MyImporterConstants.TAG_BONE_MAPPING] as VRageMath.Vector3I[]; if (tagData.ContainsKey(MyImporterConstants.TAG_MODEL_FRACTURES)) { ModelFractures = (MyModelFractures)tagData[MyImporterConstants.TAG_MODEL_FRACTURES]; } object patternScale; if (tagData.TryGetValue(MyImporterConstants.TAG_PATTERN_SCALE, out patternScale)) { PatternScale = (float)patternScale; } if (BoneMapping.Length == 0) { BoneMapping = null; } if (tagData.ContainsKey(MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY)) { HavokData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY]; byte[] tagCollisionData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_COLLISION_GEOMETRY]; if (tagCollisionData.Length > 0 && HkBaseSystem.IsThreadInitialized) { bool containsSceneData; bool containsDestructionData; List <HkShape> shapesList = new List <HkShape>(); if (!HkShapeLoader.LoadShapesListFromBuffer(tagCollisionData, shapesList, out containsSceneData, out containsDestructionData)) { MyLog.Default.WriteLine(string.Format("Model {0} - Unable to load collision geometry", AssetName), LoggingOptions.LOADING_MODELS); //Debug.Fail("Collision model was exported in wrong way: " + m_assetName); } if (shapesList.Count > 10) { MyLog.Default.WriteLine(string.Format("Model {0} - Found too many collision shapes, only the first 10 will be used", AssetName), LoggingOptions.LOADING_MODELS); } if (HavokCollisionShapes != null) { Debug.Fail("Shapes already loaded"); } if (shapesList.Count > 0) { HavokCollisionShapes = shapesList.ToArray(); } else { MyLog.Default.WriteLine(string.Format("Model {0} - Unable to load collision geometry from file, default collision will be used !", AssetName)); } if (containsDestructionData) { HavokDestructionData = tagCollisionData; } ExportedWrong = !containsSceneData; } } if (tagData.ContainsKey(MyImporterConstants.TAG_HAVOK_DESTRUCTION)) { if (((byte[])tagData[MyImporterConstants.TAG_HAVOK_DESTRUCTION]).Length > 0) { HavokDestructionData = (byte[])tagData[MyImporterConstants.TAG_HAVOK_DESTRUCTION]; } } VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("Model - load data - copy triangle indices"); // Prepare data CopyTriangleIndices(); m_trianglesCount = Triangles.Length; // Remember this numbers as list may be cleared at the end of this method VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); MyLog.Default.WriteLine("Triangles.Length: " + Triangles.Length, LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("Vertexes.Length: " + GetVerticesCount(), LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("Centered: " + (bool)tagData[MyImporterConstants.TAG_CENTERED], LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("UseChannelTextures: " + (bool)tagData[MyImporterConstants.TAG_USE_CHANNEL_TEXTURES], LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("Length in meters: " + (float)tagData[MyImporterConstants.TAG_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("Rescale to length in meters?: " + (bool)tagData[MyImporterConstants.TAG_RESCALE_TO_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("BoundingBox: " + BoundingBox, LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("BoundingSphere: " + BoundingSphere, LoggingOptions.LOADING_MODELS); VRage.Utils.Stats.PerAppLifetime.MyModelsCount++; VRage.Utils.Stats.PerAppLifetime.MyModelsMeshesCount += m_meshContainer.Count; VRage.Utils.Stats.PerAppLifetime.MyModelsVertexesCount += GetVerticesCount(); VRage.Utils.Stats.PerAppLifetime.MyModelsTrianglesCount += Triangles.Length; ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize); m_loadedData = true; m_loadingErrorProcessed = false; MyLog.Default.DecreaseIndent(LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("MyModel.LoadData -> END", LoggingOptions.LOADING_MODELS); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } }