internal void AddSphereRing(BoundingSphere sphere, Color color, Matrix onb) { float increment = 1.0f / 32; for (float i = 0; i < 1; i += increment) { float a0 = 2 * (float)Math.PI * i; float a1 = 2 * (float)Math.PI * (i + increment); Add( Vector3.Transform(new Vector3(Math.Cos(a0), 0, Math.Sin(a0)) * sphere.Radius, onb) + sphere.Center, Vector3.Transform(new Vector3(Math.Cos(a1), 0, Math.Sin(a1)) * sphere.Radius, onb) + sphere.Center, color); } }
public void InitLazy(MyObjectBuilder_DefinitionBase baseBuilder) { MyObjectBuilder_PrefabDefinition definition = baseBuilder as MyObjectBuilder_PrefabDefinition; if ((definition.CubeGrid != null) || (definition.CubeGrids != null)) { if (definition.CubeGrid == null) { this.m_cubeGrids = definition.CubeGrids; } else { this.m_cubeGrids = new MyObjectBuilder_CubeGrid[] { definition.CubeGrid }; } this.m_boundingSphere = new VRageMath.BoundingSphere(Vector3.Zero, float.MinValue); this.m_boundingBox = VRageMath.BoundingBox.CreateInvalid(); MyObjectBuilder_CubeGrid[] cubeGrids = this.m_cubeGrids; int index = 0; while (index < cubeGrids.Length) { Matrix identity; MyObjectBuilder_CubeGrid grid = cubeGrids[index]; VRageMath.BoundingBox box = grid.CalculateBoundingBox(); if (grid.PositionAndOrientation == null) { identity = Matrix.Identity; } else { identity = (Matrix)grid.PositionAndOrientation.Value.GetMatrix(); } this.m_boundingBox.Include(box.Transform(identity)); index++; } this.m_boundingSphere = VRageMath.BoundingSphere.CreateFromBoundingBox(this.m_boundingBox); cubeGrids = this.m_cubeGrids; for (index = 0; index < cubeGrids.Length; index++) { MyObjectBuilder_CubeGrid grid1 = cubeGrids[index]; grid1.CreatePhysics = true; grid1.XMirroxPlane = null; grid1.YMirroxPlane = null; grid1.ZMirroxPlane = null; } this.Initialized = true; } }
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(); if (tagData.Count == 0) { throw new Exception(String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName)); } 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; VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize); 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"); 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 (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(); } } 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.Count(); // 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); Stats.PerAppLifetime.MyModelsCount++; Stats.PerAppLifetime.MyModelsMeshesCount += m_meshContainer.Count; Stats.PerAppLifetime.MyModelsVertexesCount += GetVerticesCount(); 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(); } }
// 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; if (m_loadedContent) return; lock (this) { if (m_loadedData) return; if (m_loadedContent) return; MyRender.GetRenderProfiler().StartProfilingBlock("MyModel::LoadData"); MyRender.Log.WriteLine("MyModel.LoadData -> START", LoggingOptions.LOADING_MODELS); MyRender.Log.IncreaseIndent(LoggingOptions.LOADING_MODELS); MyRender.Log.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. MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - import data"); string assetForImport = AssetName; var fsPath = Path.IsPathRooted(AssetName) ? AssetName : Path.Combine(MyFileSystem.ContentPath, AssetName); if (!MyFileSystem.FileExists(fsPath)) { MyRender.Log.WriteLine("ERROR: Asset " + AssetName + "not exists!"); assetForImport = @"Models\Debug\Error.mwm"; } MyRender.Log.WriteLine(String.Format("Importing asset {0}, path: {1}", assetForImport, AssetName), LoggingOptions.LOADING_MODELS); try { m_importer.ImportData(assetForImport); } catch { MyRender.Log.WriteLine(String.Format("Importing asset failed {0}", m_assetName)); throw; } MyRender.GetRenderProfiler().EndProfilingBlock(); MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - load tag data"); Dictionary<string, object> tagData = m_importer.GetTagData(); if (tagData.Count == 0) { throw new Exception(String.Format("Uncompleted tagData for asset: {0}, path: {1}", m_assetName, AssetName)); } MyRender.GetRenderProfiler().EndProfilingBlock(); MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - vertex, normals, texture coords"); object patternScale; if (tagData.TryGetValue(MyImporterConstants.TAG_PATTERN_SCALE, out patternScale)) { PatternScale = (float)patternScale; } HalfVector4[] vertices = (HalfVector4[])tagData[MyImporterConstants.TAG_VERTICES]; //Dont assert, it can be animation //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; HalfVector2[] forLoadingTexCoords0 = (HalfVector2[])tagData[MyImporterConstants.TAG_TEXCOORDS0]; m_forLoadingTexCoords0 = new HalfVector2[forLoadingTexCoords0.Length]; for (int t = 0; t < forLoadingTexCoords0.Length; t++) { m_forLoadingTexCoords0[t] = forLoadingTexCoords0[t];// new HalfVector2(forLoadingTexCoords0[t]); m_forLoadingTexCoords0[t] = new HalfVector2(m_forLoadingTexCoords0[t].ToVector2() / PatternScale); } MyRender.GetRenderProfiler().EndProfilingBlock(); MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - mesh"); 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) { if (meshPart.m_MaterialDesc != null) MyRenderModels.Materials[meshPart.m_MaterialDesc.MaterialName] = meshPart.m_MaterialDesc; MyRenderMesh mesh = new MyRenderMesh(meshPart, m_assetName); mesh.IndexStart = indices.Count; mesh.TriCount = meshPart.m_indices.Count / 3; System.Diagnostics.Debug.Assert(mesh.TriCount > 0); foreach (var i in meshPart.m_indices) { indices.Add(i); if (i > maxIndex) { maxIndex = i; } } m_meshContainer.Add(mesh); if (meshPart.m_MaterialDesc != null && meshPart.Technique == MyMeshDrawTechnique.GLASS) { float minimumGlassShadow = 0.0f; if (string.IsNullOrEmpty(meshPart.m_MaterialDesc.GlassCW)) continue; if (string.IsNullOrEmpty(meshPart.m_MaterialDesc.GlassCCW)) continue; var materialCW = MyTransparentMaterials.GetMaterial(meshPart.m_MaterialDesc.GlassCW); var materialCCW = MyTransparentMaterials.GetMaterial(meshPart.m_MaterialDesc.GlassCCW); mesh.GlassDithering = System.Math.Max(materialCW.Color.W, minimumGlassShadow); MyRenderMesh glassMesh = new MyRenderMesh(meshPart, m_assetName); glassMesh.GlassDithering = System.Math.Max(materialCCW.Color.W, minimumGlassShadow); glassMesh.IndexStart = indices.Count; glassMesh.TriCount = meshPart.m_indices.Count / 3; System.Diagnostics.Debug.Assert(glassMesh.TriCount > 0); for (int i = 0; i < meshPart.m_indices.Count; i += 3) { indices.Add(meshPart.m_indices[i + 0]); indices.Add(meshPart.m_indices[i + 2]); indices.Add(meshPart.m_indices[i + 1]); } m_meshContainer.Add(glassMesh); } } 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_trianglesCount = indices.Count / 3; } MyRender.GetRenderProfiler().EndProfilingBlock(); MyRender.GetRenderProfiler().StartProfilingBlock("Model - load data - other data"); if (MyRenderConstants.RenderQualityProfile.UseNormals && m_forLoadingTexCoords0.Length > 0) { var verticesNum = vertices.Length; Byte4[] forLoadingTangents = (Byte4[])tagData[MyImporterConstants.TAG_TANGENTS]; Byte4[] forLoadingBitangents = (Byte4[])tagData[MyImporterConstants.TAG_BINORMALS]; m_forLoadingTangents = new Byte4[forLoadingTangents.Length]; for (int v = 0; v < forLoadingTangents.Length; v++) { var N = VF_Packer.UnpackNormal(m_vertices[v].Normal.PackedValue); var T = VF_Packer.UnpackNormal(forLoadingTangents[v].PackedValue); var B = VF_Packer.UnpackNormal(forLoadingBitangents[v].PackedValue); var tangentSign = new Vector4(T.X, T.Y, T.Z, 0); tangentSign.W = T.Cross(N).Dot(B) < 0 ? -1 : 1; m_forLoadingTangents[v] = VF_Packer.PackTangentSignB4(ref tangentSign); } } m_specularShininess = (float)tagData[MyImporterConstants.TAG_SPECULAR_SHININESS]; m_specularPower = (float)tagData[MyImporterConstants.TAG_SPECULAR_POWER]; m_rescaleFactor = (float)tagData[MyImporterConstants.TAG_RESCALE_FACTOR]; BoneIndices = (Vector4I[])tagData[MyImporterConstants.TAG_BLENDINDICES]; BoneWeights = (Vector4[])tagData[MyImporterConstants.TAG_BLENDWEIGHTS]; Animations = (ModelAnimations)tagData[MyImporterConstants.TAG_ANIMATIONS]; Bones = (MyModelBone[])tagData[MyImporterConstants.TAG_BONES]; if(BoneIndices.Length > 0 && Bones.Length > MyRenderConstants.MAX_SHADER_BONES) { List<MyMeshPartInfo> meshParts = tagData[MyImporterConstants.TAG_MESH_PARTS] as List<MyMeshPartInfo>; Dictionary<int, int> vertexChanged = new Dictionary<int,int>(); for(int p=0; p<meshParts.Count; p++) { var meshPart = meshParts[p]; Dictionary<int, int> bonesUsed = new Dictionary<int, int>(); int trianglesNum = meshPart.m_indices.Count / 3; for (int i = 0; i < trianglesNum; i++) { for (int j = 0; j < 3; j++) { int index = meshPart.m_indices[i * 3 + j]; if(BoneWeights[index].X > 0) bonesUsed[BoneIndices[index].X] = 1; if (BoneWeights[index].Y > 0) bonesUsed[BoneIndices[index].Y] = 1; if (BoneWeights[index].Z > 0) bonesUsed[BoneIndices[index].Z] = 1; if (BoneWeights[index].W > 0) bonesUsed[BoneIndices[index].W] = 1; } } var partBones = new List<int>(bonesUsed.Keys); partBones.Sort(); if (partBones.Count > 0 && partBones[partBones.Count - 1] >= MyRenderConstants.MAX_SHADER_BONES) { for(int i=0; i<partBones.Count; i++) { bonesUsed[partBones[i]] = i; } Dictionary<int, int> vertexTouched = new Dictionary<int, int>(); for (int i = 0; i < trianglesNum; i++) { for (int j = 0; j < 3; j++) { int index = meshPart.m_indices[i * 3 + j]; if(!vertexTouched.ContainsKey(index)) { if (BoneWeights[index].X > 0) BoneIndices[index].X = bonesUsed[BoneIndices[index].X]; if (BoneWeights[index].Y > 0) BoneIndices[index].Y = bonesUsed[BoneIndices[index].Y]; if (BoneWeights[index].Z > 0) BoneIndices[index].Z = bonesUsed[BoneIndices[index].Z]; if (BoneWeights[index].W > 0) BoneIndices[index].W = bonesUsed[BoneIndices[index].W]; vertexTouched[index] = 1; int changes = 0; vertexChanged.TryGetValue(index, out changes); vertexChanged[index] = changes + 1; } } } m_meshContainer[p].BonesUsed = partBones.ToArray(); } } if (vertexChanged.Values.Count > 0) Debug.Assert(vertexChanged.Values.Max() < 2, "Vertex shared between model parts, will likely result in wrong skinning"); } BoundingBox = (BoundingBox)tagData[MyImporterConstants.TAG_BOUNDING_BOX]; BoundingSphere = (BoundingSphere)tagData[MyImporterConstants.TAG_BOUNDING_SPHERE]; BoundingBoxSize = BoundingBox.Max - BoundingBox.Min; BoundingBoxSizeHalf = BoundingBoxSize / 2.0f; Dictionary<string, MyModelDummy> Dummies = tagData[MyImporterConstants.TAG_DUMMIES] as Dictionary<string, MyModelDummy>; MyRender.GetRenderProfiler().EndProfilingBlock(); if (tagData.ContainsKey(MyImporterConstants.TAG_LODS)) { var tagLODs = tagData[MyImporterConstants.TAG_LODS]; LODs.Clear(); LODs.AddArray((MyLODDescriptor[])tagLODs); foreach (var lodDesc in LODs) { if (!string.IsNullOrEmpty(lodDesc.RenderQuality)) { lodDesc.RenderQualityList = new List<int>(); string[] qualityStrings = lodDesc.RenderQuality.ToUpper().Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries); foreach (string qs in qualityStrings) { string qs2 = qs.Trim(); if (qs2 == "LOW") lodDesc.RenderQualityList.Add((int)MyRenderQualityEnum.LOW); else if (qs2 == "NORMAL") lodDesc.RenderQualityList.Add((int)MyRenderQualityEnum.NORMAL); else if (qs2 == "HIGH") lodDesc.RenderQualityList.Add((int)MyRenderQualityEnum.HIGH); else if (qs2 == "EXTREME") lodDesc.RenderQualityList.Add((int)MyRenderQualityEnum.EXTREME); } } } } MyRender.Log.WriteLine("Vertexes.Length: " + GetVerticesCount(), LoggingOptions.LOADING_MODELS); MyRender.Log.WriteLine("Centered: " + (bool)tagData[MyImporterConstants.TAG_CENTERED], LoggingOptions.LOADING_MODELS); MyRender.Log.WriteLine("UseChannelTextures: " + (bool)tagData[MyImporterConstants.TAG_USE_CHANNEL_TEXTURES], LoggingOptions.LOADING_MODELS); MyRender.Log.WriteLine("Length in meters: " + (float)tagData[MyImporterConstants.TAG_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS); MyRender.Log.WriteLine("Rescale to length in meters?: " + (bool)tagData[MyImporterConstants.TAG_RESCALE_TO_LENGTH_IN_METERS], LoggingOptions.LOADING_MODELS); MyRender.Log.WriteLine("SpecularShininess: " + m_specularShininess, LoggingOptions.LOADING_MODELS); MyRender.Log.WriteLine("SpecularPower: " + m_specularPower, LoggingOptions.LOADING_MODELS); MyRender.Log.WriteLine("RescaleFactor: " + m_rescaleFactor, LoggingOptions.LOADING_MODELS); MyRender.Log.WriteLine("BoundingBox: " + BoundingBox, LoggingOptions.LOADING_MODELS); MyRender.Log.WriteLine("BoundingSphere: " + BoundingSphere, LoggingOptions.LOADING_MODELS); MyPerformanceCounter.PerAppLifetime.MyModelsCount++; MyPerformanceCounter.PerAppLifetime.MyModelsMeshesCount += m_meshContainer.Count; MyPerformanceCounter.PerAppLifetime.MyModelsVertexesCount += GetVerticesCount(); MyPerformanceCounter.PerAppLifetime.MyModelsTrianglesCount += m_trianglesCount; ModelInfo = new MyModelInfo(GetTrianglesCount(), GetVerticesCount(), BoundingBoxSize); m_loadedData = true; m_importer.Clear(); MyRender.Log.DecreaseIndent(LoggingOptions.LOADING_MODELS); MyRender.Log.WriteLine("MyModel.LoadData -> END", LoggingOptions.LOADING_MODELS); MyRender.GetRenderProfiler().EndProfilingBlock(); } }
public void LoadBuffers(MyModelData modelData, string assetName = null) { System.Diagnostics.Debug.Assert(modelData.Sections.Count > 0, "Invalid object"); if (modelData.Sections.Count == 0) return; // create index buffer { m_trianglesCount = modelData.Indices.Count / 3; m_Indices_16bit = new ushort[modelData.Indices.Count]; for (int i = 0; i < modelData.Indices.Count; ++i) m_Indices_16bit[i] = (ushort)modelData.Indices[i]; m_indexBuffer = new IndexBuffer(MyRender.GraphicsDevice, m_Indices_16bit.Length * sizeof(short), Usage.WriteOnly, Pool.Default, true); m_indexBuffer.SetData(m_Indices_16bit); m_indexBuffer.Tag = this; m_indexBufferSize = m_Indices_16bit.Length * sizeof(short); SignResource(m_indexBuffer); } // create vertex buffer { m_verticesCount = modelData.Positions.Count; m_vertices = new MyCompressedVertexNormal[m_verticesCount]; var vertexArray = new MyVertexFormatPositionNormalTextureTangent[m_verticesCount]; for (int i = 0; i < modelData.Positions.Count; ++i) { vertexArray[i].Position = modelData.Positions[i]; vertexArray[i].Normal = modelData.Normals[i]; vertexArray[i].Tangent = modelData.Tangents[i]; vertexArray[i].TexCoord = modelData.TexCoords[i]; m_vertices[i] = new MyCompressedVertexNormal() { Position = vertexArray[i].PositionPacked, Normal = vertexArray[i].NormalPacked }; } m_vertexDeclaration = MyVertexFormatPositionNormalTextureTangent.VertexDeclaration; m_vertexStride = MyVertexFormatPositionNormalTextureTangent.Stride; m_vertexBufferSize = vertexArray.Length * m_vertexStride; m_vertexBuffer = new VertexBuffer(MyRender.GraphicsDevice, m_vertexBufferSize, Usage.WriteOnly, VertexFormat.None, Pool.Default); m_vertexBuffer.SetData(vertexArray); m_vertexBuffer.Tag = this; SignResource(m_vertexBuffer); } m_meshContainer.Clear(); // apply materials here for (int s = 0; s < modelData.Sections.Count; ++s) { var mpi = new MyMeshPartInfo(); mpi.Technique = m_drawTechnique; // Disabled, because it assert always when models are loaded before materials //System.Diagnostics.Debug.Assert(MyRenderModels.Materials.ContainsKey(modelData.Sections[s].MaterialName), "Mesh material not present!"); if (MyRenderModels.Materials.ContainsKey(modelData.Sections[s].MaterialName)) mpi.m_MaterialDesc = MyRenderModels.Materials[modelData.Sections[s].MaterialName]; var start = modelData.Sections[s].IndexStart; var end = start + modelData.Sections[s].TriCount*3; for (int i = start; i < end; ++i) mpi.m_indices.Add(modelData.Indices[i]); m_meshContainer.Add(new MyRenderMesh(mpi, null) { IndexStart = modelData.Sections[s].IndexStart, TriCount = modelData.Sections[s].TriCount }); } // store properties of this model { BoundingBox = modelData.AABB; BoundingSphere = new BoundingSphere(modelData.AABB.Center, modelData.AABB.HalfExtents.Length()); BoundingBoxSize = BoundingBox.Size; BoundingBoxSizeHalf = BoundingBox.HalfExtents; ModelInfo = new MyModelInfo(m_trianglesCount, m_verticesCount, BoundingBoxSize); PreloadTextures(LoadingMode.Immediate); LoadState = Textures.LoadState.Loaded; m_loadedContent = true; m_loadedData = true; } }
private static void ProcessMessageInternal(MyRenderMessageBase message) { switch (message.MessageType) { #region Sprites case MyRenderMessageEnum.DrawSprite: case MyRenderMessageEnum.DrawSpriteNormalized: case MyRenderMessageEnum.DrawSpriteAtlas: case MyRenderMessageEnum.SpriteScissorPush: case MyRenderMessageEnum.SpriteScissorPop: { EnqueueDrawMessage(message); break; } #endregion #region Textures case MyRenderMessageEnum.PreloadTextures: { var preloadMsg = message as MyRenderMessagePreloadTextures; MyTextureManager.PreloadTextures(preloadMsg.InDirectory, preloadMsg.Recursive); break; } case MyRenderMessageEnum.UnloadTexture: { var texMessage = (MyRenderMessageUnloadTexture)message; MyTextureManager.UnloadTexture(texMessage.Texture); break; } #endregion #region Profiler case MyRenderMessageEnum.RenderProfiler: { var profMessage = (MyRenderMessageRenderProfiler)message; MyRenderProfiler.HandleInput(profMessage.Command, profMessage.Index); break; } #endregion #region Render objects case MyRenderMessageEnum.CreateRenderEntity: { var rMessage = (MyRenderMessageCreateRenderEntity)message; MyRenderEntity renderEntity; // AlesR : refactor if (string.IsNullOrEmpty(rMessage.Model)) { ProfilerShort.Begin("CreateRenderEntity-NoModel"); renderEntity = new MyRenderEntity( rMessage.ID, rMessage.DebugName, rMessage.WorldMatrix, rMessage.Technique, rMessage.Flags ); ProfilerShort.BeginNextBlock("SetMaxDist"); renderEntity.MaxViewDistance = rMessage.MaxViewDistance; ProfilerShort.End(); } else { ProfilerShort.Begin("CreateRenderEntity-Model"); renderEntity = new MyRenderEntity( rMessage.ID, rMessage.DebugName, rMessage.Model, rMessage.WorldMatrix, rMessage.Technique, rMessage.Flags ); ProfilerShort.End(); if (renderEntity.Lods.Count == 0) return; ProfilerShort.Begin("SetMaxDist"); renderEntity.MaxViewDistance = rMessage.MaxViewDistance; ProfilerShort.End(); ProfilerShort.Begin("renderEntity.LoadContent"); renderEntity.LoadContent(); ProfilerShort.End(); } ProfilerShort.Begin("AddRenderObjectFromProxy"); AddRenderObjectFromProxy(renderEntity); ProfilerShort.End(); break; } case MyRenderMessageEnum.CreateRenderEntityAtmosphere: { var rMessage = (MyRenderMessageCreateRenderEntityAtmosphere)message; MyRenderEntity renderEntity; ProfilerShort.Begin("CreateRenderEntity-Atmosphere"); renderEntity = new MyRenderAtmosphere( rMessage.ID, rMessage.DebugName, rMessage.Model, rMessage.WorldMatrix, rMessage.Technique, rMessage.Flags, rMessage.AtmosphereRadius, rMessage.PlanetRadius, rMessage.AtmosphereWavelengths ); ProfilerShort.End(); if (renderEntity.Lods.Count == 0) return; ProfilerShort.Begin("SetMaxDist"); renderEntity.MaxViewDistance = rMessage.MaxViewDistance; ProfilerShort.End(); ProfilerShort.Begin("renderEntity.LoadContent"); renderEntity.LoadContent(); ProfilerShort.End(); ProfilerShort.Begin("AddRenderObjectFromProxy"); AddRenderObjectFromProxy(renderEntity); ProfilerShort.End(); break; } case MyRenderMessageEnum.AddRuntimeModel: { var rMessage = (MyRenderMessageAddRuntimeModel)message; var model = new MyRenderModel(MyMeshDrawTechnique.MESH); ProfilerShort.Begin("LoadBuffers"); model.LoadBuffers(rMessage.ModelData); ProfilerShort.End(); MyRenderModels.AddRuntimeModel(rMessage.Name, model); break; } case MyRenderMessageEnum.PreloadModel: { var rMessage = (MyRenderMessagePreloadModel)message; MyRenderModels.GetModel(rMessage.Name); break; } case MyRenderMessageEnum.UnloadModel: { var rMessage = (MyRenderMessageUnloadModel)message; MyRenderModels.UnloadModel(rMessage.Name); break; } case MyRenderMessageEnum.PreloadMaterials: { var rMessage = (MyRenderMessagePreloadMaterials)message; MyRenderModels.GetMaterials(rMessage.Name); break; } case MyRenderMessageEnum.SetRenderEntityData: { var rMessage = (MyRenderMessageSetRenderEntityData)message; var entity = (MyRenderEntity)GetRenderObject(rMessage.ID); if (entity != null) entity.AddData(rMessage); break; } case MyRenderMessageEnum.SetRenderEntityLOD: { var rMessage = (MyRenderMessageSetRenderEntityLOD)message; var entity = (MyRenderEntity)GetRenderObject(rMessage.ID); if (entity != null) { entity.AddLOD(rMessage.Distance, rMessage.Model); } break; } case MyRenderMessageEnum.CreateRenderBatch: { var rMessage = (MyRenderMessageCreateRenderBatch)message; MyRenderBatch renderBatch = new MyRenderBatch( rMessage.ID, rMessage.DebugName, (MatrixD)rMessage.WorldMatrix, rMessage.Flags, rMessage.RenderBatchParts ); renderBatch.LoadContent(); AddRenderObjectFromProxy(renderBatch); break; } case MyRenderMessageEnum.CreateRenderInstanceBuffer: { var rMessage = (MyRenderMessageCreateRenderInstanceBuffer)message; MyRenderInstanceBuffer renderBatch = new MyRenderInstanceBuffer(rMessage.ID, rMessage.DebugName, rMessage.Type); renderBatch.LoadContent(); AddRenderObjectFromProxy(renderBatch); break; } case MyRenderMessageEnum.CreateLineBasedObject: { var rMessage = (MyRenderMessageCreateLineBasedObject)message; var lineBasedObj = new MyRenderLineBasedObject(rMessage.ID, rMessage.DebugName); lineBasedObj.LoadContent(); AddRenderObjectFromProxy(lineBasedObj); break; } case MyRenderMessageEnum.UpdateLineBasedObject: { var rMessage = (MyRenderMessageUpdateLineBasedObject)message; var obj = (MyRenderLineBasedObject)GetRenderObject(rMessage.ID); if (obj != null) { obj.SetWorldPoints(ref rMessage.WorldPointA, ref rMessage.WorldPointB); UpdateRenderObject(obj); } break; } case MyRenderMessageEnum.UpdateRenderCubeInstanceBuffer: { var rMessage = (MyRenderMessageUpdateRenderCubeInstanceBuffer)message; var obj = (MyRenderInstanceBuffer)GetRenderObject(rMessage.ID); obj.UpdateCube(rMessage.InstanceData, rMessage.Capacity); rMessage.InstanceData.Clear(); break; } case MyRenderMessageEnum.UpdateRenderInstanceBuffer: { var rMessage = (MyRenderMessageUpdateRenderInstanceBuffer)message; var obj = (MyRenderInstanceBuffer)GetRenderObject(rMessage.ID); obj.Update(rMessage.InstanceData, rMessage.Capacity); rMessage.InstanceData.Clear(); break; } case MyRenderMessageEnum.SetInstanceBuffer: { var rMessage = (MyRenderMessageSetInstanceBuffer)message; var entity = (MyRenderEntity)GetRenderObject(rMessage.ID); if (entity != null) { //RemoveRenderObject(entity); var buffer = rMessage.InstanceBufferId == MyRenderProxy.RENDER_ID_UNASSIGNED ? null : (MyRenderInstanceBuffer)GetRenderObject(rMessage.InstanceBufferId); entity.SetInstanceData(buffer, rMessage.InstanceStart, rMessage.InstanceCount, (BoundingBoxD)rMessage.LocalAabb); MoveRenderObject(entity); } break; } case MyRenderMessageEnum.CreateManualCullObject: { var rMessage = (MyRenderMessageCreateManualCullObject)message; MyManualCullableRenderObject manualCullObject = new MyManualCullableRenderObject(rMessage.ID, (MatrixD)rMessage.WorldMatrix); manualCullObject.DebugName = rMessage.DebugName; manualCullObject.WorldMatrix = (MatrixD)rMessage.WorldMatrix; AddRenderObjectFromProxy(manualCullObject, false); break; } case MyRenderMessageEnum.SetParentCullObject: { var rMessage = (MyRenderMessageSetParentCullObject)message; MyRenderObject renderObject = GetRenderObject(rMessage.ID); RemoveRenderObject(renderObject); //m_renderObjects.Remove(rMessage.ID); MyManualCullableRenderObject manualCullObject = GetRenderObject(rMessage.CullObjectID) as MyManualCullableRenderObject; if (manualCullObject != null) { RemoveRenderObject(manualCullObject); manualCullObject.AddRenderObject(renderObject, (MatrixD?)rMessage.ChildToParent); AddRenderObject(manualCullObject); } else { } break; } case MyRenderMessageEnum.SetCameraViewMatrix: { var rMessage = (MyRenderMessageSetCameraViewMatrix)message; rMessage.UpdateTime = MyRender.CurrentUpdateTime; // EnqueueDrawMessage(rMessage); // var rMessage = (MyRenderMessageSetCameraViewMatrix)drawMessage; MyRenderCamera.ProjectionMatrix = rMessage.ProjectionMatrix; MyRenderCamera.ProjectionMatrixForNearObjects = rMessage.NearProjectionMatrix; MyRenderCamera.SetViewMatrix(rMessage.ViewMatrix, rMessage.UpdateTime); MyRenderCamera.SafeNearForForward = rMessage.SafeNear; MyRenderCamera.FieldOfView = rMessage.FOV; MyRenderCamera.FieldOfViewForNearObjects = rMessage.NearFOV; if ((MyRenderCamera.NEAR_PLANE_DISTANCE != rMessage.NearPlane) || (MyRenderCamera.FAR_PLANE_DISTANCE != rMessage.FarPlane) || (MyRenderCamera.NEAR_PLANE_FOR_NEAR_OBJECTS != rMessage.NearObjectsNearPlane) || (MyRenderCamera.FAR_PLANE_FOR_NEAR_OBJECTS != rMessage.NearObjectsFarPlane)) { MyRenderCamera.NEAR_PLANE_DISTANCE = rMessage.NearPlane; MyRenderCamera.FAR_PLANE_DISTANCE = rMessage.FarPlane; MyRenderCamera.NEAR_PLANE_FOR_NEAR_OBJECTS = rMessage.NearObjectsNearPlane; MyRenderCamera.FAR_PLANE_FOR_NEAR_OBJECTS = rMessage.NearObjectsFarPlane; foreach (var effect in m_effects) { if (effect != null) { effect.SetNearPlane(MyRenderCamera.NEAR_PLANE_DISTANCE); effect.SetFarPlane(MyRenderCamera.FAR_PLANE_DISTANCE); } } } MyRenderCamera.UpdateCamera(); break; } case MyRenderMessageEnum.DrawScene: { var rMessage = (MyRenderMessageBase)message; EnqueueDrawMessage(rMessage); break; } case MyRenderMessageEnum.UpdateRenderObject: { var rMessage = (MyRenderMessageUpdateRenderObject)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ID, out renderObject)) { //System.Diagnostics.Debug.Assert(renderObject.ParentCullObject == null); if (renderObject.ParentCullObject != null) { MyRenderTransformObject transformObject = renderObject as MyRenderTransformObject; if (transformObject != null) { //System.Diagnostics.Debug.Assert(Vector3D.IsZero(transformObject.WorldMatrix.Translation - rMessage.WorldMatrix.Translation, 0.01f)); } } { MyRenderCharacter characterObject = renderObject as MyRenderCharacter; if (characterObject != null) { if (rMessage.AABB.HasValue) characterObject.ActualWorldAABB = rMessage.AABB.Value; } MyRenderTransformObject transformObject = renderObject as MyRenderTransformObject; if (transformObject != null) { transformObject.WorldMatrix = rMessage.WorldMatrix; UpdateRenderObject(transformObject, rMessage.SortIntoCulling); } MyRenderClipmap clipmap = renderObject as MyRenderClipmap; if (clipmap != null) { clipmap.UpdateWorldMatrix(ref rMessage.WorldMatrix, rMessage.SortIntoCulling); UpdateRenderObject(clipmap, rMessage.SortIntoCulling); } MyManualCullableRenderObject manualCullableRenderObject = renderObject as MyManualCullableRenderObject; if (manualCullableRenderObject != null) { manualCullableRenderObject.WorldMatrix = rMessage.WorldMatrix; UpdateRenderObject(manualCullableRenderObject, rMessage.SortIntoCulling); } } } break; } case MyRenderMessageEnum.UpdateRenderObjectVisibility: { var rMessage = (MyRenderMessageUpdateRenderObjectVisibility)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ID, out renderObject)) { MyRenderTransformObject transformObject = renderObject as MyRenderTransformObject; if (transformObject != null) { transformObject.ClearInterpolator(); } MyManualCullableRenderObject manualCullableRenderObject = renderObject as MyManualCullableRenderObject; if (manualCullableRenderObject != null) { manualCullableRenderObject.ClearInterpolator(); } if (renderObject.NearFlag != rMessage.NearFlag) { var parentCullObject = renderObject.ParentCullObject; if (parentCullObject != null) { parentCullObject.RemoveRenderObject(renderObject); } RemoveRenderObject(renderObject, true); renderObject.NearFlag = rMessage.NearFlag; if (parentCullObject != null) { RemoveRenderObject(parentCullObject); parentCullObject.AddRenderObject(renderObject); AddRenderObject(parentCullObject); if (renderObject.NearFlag && !m_nearObjects.Contains(renderObject)) { m_nearObjects.Add(renderObject); } } else { AddRenderObject(renderObject); } } else { renderObject.Visible = rMessage.Visible; } } break; } case MyRenderMessageEnum.RemoveRenderObject: { var rMessage = (MyRenderMessageRemoveRenderObject)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ID, out renderObject)) { RemoveRenderObject(renderObject); m_renderObjects.Remove(rMessage.ID); renderObject.UnloadContent(); } else { } // Put breakpoint here break; } case MyRenderMessageEnum.UpdateRenderEntity: { var rMessage = (MyRenderMessageUpdateRenderEntity)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ID, out renderObject)) { MyRenderEntity renderEntity = (MyRenderEntity)renderObject; if (rMessage.DiffuseColor.HasValue) { renderEntity.EntityColor = rMessage.DiffuseColor.Value; } if (rMessage.ColorMaskHSV.HasValue) { renderEntity.EntityColorMaskHSV = rMessage.ColorMaskHSV.Value; } renderEntity.EntityDithering = rMessage.Dithering; } break; } case MyRenderMessageEnum.EnableRenderModule: { var rMessage = (MyRenderMessageEnableRenderModule)message; EnableRenderModule((MyRenderModuleEnum)rMessage.ID, rMessage.Enable); break; } case MyRenderMessageEnum.UseCustomDrawMatrix: { var rMessage = (MyRenderMessageUseCustomDrawMatrix)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ID, out renderObject)) { MyRenderEntity renderEntity = (MyRenderEntity)renderObject; renderEntity.UseCustomDrawMatrix = rMessage.Enable; renderEntity.DrawMatrix = (MatrixD)rMessage.DrawMatrix; } break; } case MyRenderMessageEnum.CreateClipmap: { var rMessage = (MyRenderMessageCreateClipmap)message; var clipmap = new MyRenderClipmap(rMessage); AddRenderObjectFromProxy(clipmap); clipmap.LoadContent(); break; } case MyRenderMessageEnum.UpdateClipmapCell: { var rMessage = (MyRenderMessageUpdateClipmapCell)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ClipmapId, out renderObject)) { var clipmap = (MyRenderClipmap)renderObject; clipmap.UpdateCell(rMessage); } break; } case MyRenderMessageEnum.InvalidateClipmapRange: { var rMessage = (MyRenderMessageInvalidateClipmapRange)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ClipmapId, out renderObject)) { var clipmap = (MyRenderClipmap)renderObject; clipmap.InvalidateRange(rMessage.MinCellLod0, rMessage.MaxCellLod0); } break; } case MyRenderMessageEnum.RebuildCullingStructure: { MyRender.RebuildCullingStructure(); break; } case MyRenderMessageEnum.ReloadGrass: case MyRenderMessageEnum.ReloadEffects: { MyRender.RootDirectoryEffects = MyRender.RootDirectoryDebug; //MyRender.RootDirectoryEffects = MyRender.RootDirectory; MyRender.LoadEffects(); break; } case MyRenderMessageEnum.ReloadModels: { MyRenderModels.ReloadModels(); break; } case MyRenderMessageEnum.ReloadTextures: { MyTextureManager.ReloadTextures(false); break; } case MyRenderMessageEnum.CreateRenderVoxelMaterials: { MyRenderVoxelMaterials.Clear(); var rMessage = (MyRenderMessageCreateRenderVoxelMaterials)message; for (int i = 0; i < rMessage.Materials.Length; ++i) MyRenderVoxelMaterials.Add(ref rMessage.Materials[i]); rMessage.Materials = null; break; } case MyRenderMessageEnum.UpdateRenderVoxelMaterials: { MyRenderVoxelMaterials.Clear(); var rMessage = (MyRenderMessageUpdateRenderVoxelMaterials)message; MyRenderVoxelMaterials.Add(ref rMessage.Materials[0]); rMessage.Materials = null; break; } case MyRenderMessageEnum.CreateRenderVoxelDebris: { var rMessage = (MyRenderMessageCreateRenderVoxelDebris)message; MyRenderVoxelDebris renderVoxelDebris = new MyRenderVoxelDebris( rMessage.ID, rMessage.DebugName, rMessage.Model, (MatrixD)rMessage.WorldMatrix, rMessage.TextureCoordOffset, rMessage.TextureCoordScale, rMessage.TextureColorMultiplier, rMessage.VoxelMaterialIndex ); AddRenderObjectFromProxy(renderVoxelDebris); break; } case MyRenderMessageEnum.CreateRenderCharacter: { var rMessage = (MyRenderMessageCreateRenderCharacter)message; MyRenderCharacter renderCharacter = new MyRenderCharacter( rMessage.ID, rMessage.DebugName, rMessage.Model, (MatrixD)rMessage.WorldMatrix, rMessage.Flags ); AddRenderObjectFromProxy(renderCharacter); break; } case MyRenderMessageEnum.UpdateModelProperties: { var rMessage = (MyRenderMessageUpdateModelProperties)message; if (rMessage.ID == MyRenderProxy.RENDER_ID_UNASSIGNED) { MyRenderModel model = MyRenderModels.GetModel(rMessage.Model); MyRenderMesh mesh = null; if (rMessage.MaterialName != null) { foreach (var rMesh in model.GetMeshList()) { if (rMesh.Material.MaterialName == rMessage.MaterialName) { mesh = rMesh; break; } } } else mesh = model.GetMeshList()[rMessage.MeshIndex]; if (mesh != null) { MyRenderMeshMaterial material = mesh.Material; if (rMessage.Enabled.HasValue) material.Enabled = rMessage.Enabled.Value; if (rMessage.DiffuseColor.HasValue) material.DiffuseColor = rMessage.DiffuseColor.Value.ToVector3(); if (rMessage.SpecularIntensity.HasValue) material.SpecularIntensity = rMessage.SpecularIntensity.Value; if (rMessage.SpecularPower.HasValue) material.SpecularPower = rMessage.SpecularPower.Value; if (rMessage.Emissivity.HasValue) material.Emissivity = rMessage.Emissivity.Value; } model.HasSharedMaterials = true; } else { MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ID, out renderObject)) { MyRenderEntity renderEntity = renderObject as MyRenderEntity; List<MyRenderMeshMaterial> materials = renderEntity.Lods[rMessage.LOD].MeshMaterials; MyRenderModel model = renderEntity.Lods[rMessage.LOD].Model; MyRenderMeshMaterial material = null; model.HasSharedMaterials = false; if (rMessage.MaterialName != null) { foreach (var rMaterial in materials) { if (rMaterial.MaterialName == rMessage.MaterialName) { material = rMaterial; break; } } } else material = materials[rMessage.MeshIndex]; if (material != null) { if (rMessage.Enabled.HasValue) material.Enabled = rMessage.Enabled.Value; if (rMessage.DiffuseColor.HasValue) material.DiffuseColor = rMessage.DiffuseColor.Value.ToVector3(); if (rMessage.SpecularIntensity.HasValue) material.SpecularIntensity = rMessage.SpecularIntensity.Value; if (rMessage.SpecularPower.HasValue) material.SpecularPower = rMessage.SpecularPower.Value; if (rMessage.Emissivity.HasValue) material.Emissivity = rMessage.Emissivity.Value; } } } break; } case MyRenderMessageEnum.UpdateColorEmissivity: { var rMessage = (MyRenderMessageUpdateColorEmissivity)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ID, out renderObject)) { MyRenderEntity renderEntity = renderObject as MyRenderEntity; List<MyRenderMeshMaterial> materials = renderEntity.Lods[rMessage.LOD].MeshMaterials; MyRenderModel model = renderEntity.Lods[rMessage.LOD].Model; MyRenderMeshMaterial material = null; model.HasSharedMaterials = false; if (rMessage.MaterialName != null) { foreach (var rMaterial in materials) { if (rMaterial.MaterialName == rMessage.MaterialName) { material = rMaterial; break; } } } if (material != null) { material.DiffuseColor = rMessage.DiffuseColor.ToVector3(); material.Emissivity = rMessage.Emissivity; } } break; } case MyRenderMessageEnum.ChangeModel: { var rMessage = (MyRenderMessageChangeModel)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ID, out renderObject)) { MyRenderEntity entity = renderObject as MyRenderEntity; if (rMessage.UseForShadow) { entity.ChangeShadowModels(rMessage.LOD, rMessage.Model); entity.ChangeModels(rMessage.LOD, rMessage.Model); } else { entity.ChangeShadowModels(rMessage.LOD, entity.Lods[rMessage.LOD].Model.AssetName); entity.ChangeModels(rMessage.LOD, rMessage.Model); } } break; } case MyRenderMessageEnum.UpdateGameplayFrame: { var rMessage = (MyRenderMessageUpdateGameplayFrame)message; Settings.GameplayFrame = rMessage.GameplayFrame; break; } case MyRenderMessageEnum.UpdateVoxelMaterialsProperties: { var rMessage = (MyRenderMessageUpdateVoxelMaterialsProperties)message; var material = MyRenderVoxelMaterials.Get(rMessage.MaterialIndex); material.SpecularIntensity = rMessage.SpecularIntensity; material.SpecularPower = rMessage.SpecularPower; break; } case MyRenderMessageEnum.ChangeMaterialTexture: { var rMessage = (MyRenderMessageChangeMaterialTexture)message; MyRenderMeshMaterial material = GetMeshMaterial(rMessage.RenderObjectID, rMessage.MaterialName); if (material != null) { material.DiffuseTexture = MyTextureManager.GetTexture<MyTexture2D>(rMessage.Changes[0].TextureName, "", null, LoadingMode.Immediate); } rMessage.Changes.Clear(); break; } case MyRenderMessageEnum.DrawTextToMaterial: { var rMessage = (MyRenderMessageDrawTextToMaterial)message; MyRenderMeshMaterial material = GetMeshMaterial(rMessage.RenderObjectID, rMessage.MaterialName); if (material != null) { var id = new MyRenderTextureId(); id.EntityId = rMessage.EntityId; id.RenderObjectId = rMessage.RenderObjectID; material.DiffuseTexture = MyRender.RenderTextToTexture(id, rMessage.Text, rMessage.TextScale , rMessage.FontColor, rMessage.BackgroundColor, rMessage.TextureResolution, rMessage.TextureAspectRatio); if (material.DiffuseTexture == null) { MyRenderProxy.TextNotDrawnToTexture(rMessage.EntityId); } } break; } case MyRenderMessageEnum.ReleaseRenderTexture: { var rMessage = (MyRenderMessageReleaseRenderTexture)message; var id = new MyRenderTextureId(); id.EntityId = rMessage.EntityId; id.RenderObjectId = rMessage.RenderObjectID; if (MyRenderTexturePool.ReleaseRenderTexture(id)) { MyRenderProxy.RenderTextureFreed(MyRenderTexturePool.FreeResourcesCount()); } break; } #endregion #region Lights case MyRenderMessageEnum.CreateRenderLight: { var rMessage = (MyRenderMessageCreateRenderLight)message; MyRenderLight renderLight = new MyRenderLight( rMessage.ID ); AddRenderObjectFromProxy(renderLight); break; } case MyRenderMessageEnum.UpdateRenderLight: { var rMessage = (MyRenderMessageUpdateRenderLight)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ID, out renderObject)) { MyRenderLight renderLight = renderObject as MyRenderLight; if (renderLight != null) { bool dirtyAABB = false; if (renderLight.m_parentID != rMessage.ParentID) dirtyAABB = true; if (renderLight.m_position != rMessage.Position) dirtyAABB = true; renderLight.UpdateParameters( rMessage.Type, rMessage.Position, rMessage.ParentID, rMessage.Offset, rMessage.Color, rMessage.SpecularColor, rMessage.Falloff, rMessage.Range, rMessage.Intensity, rMessage.LightOn, rMessage.UseInForwardRender, rMessage.ReflectorIntensity, rMessage.ReflectorOn, rMessage.ReflectorDirection, rMessage.ReflectorUp, rMessage.ReflectorConeMaxAngleCos, rMessage.ReflectorColor, rMessage.ReflectorRange, rMessage.ReflectorFalloff, rMessage.ReflectorTexture, rMessage.ShadowDistance, rMessage.CastShadows, rMessage.GlareOn, rMessage.GlareType, rMessage.GlareSize, rMessage.GlareQuerySize, rMessage.GlareIntensity, rMessage.GlareMaterial, rMessage.GlareMaxDistance ); if (dirtyAABB) UpdateRenderObject(renderLight, false); } } break; } case MyRenderMessageEnum.SetLightShadowIgnore: { var rMessage = (MyRenderMessageSetLightShadowIgnore)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ID, out renderObject)) { MyRenderLight renderLight = (MyRenderLight)renderObject; renderLight.ShadowIgnoreObjects.Add(rMessage.ID2); } break; } case MyRenderMessageEnum.ClearLightShadowIgnore: { var rMessage = (MyRenderMessageClearLightShadowIgnore)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ID, out renderObject)) { MyRenderLight renderLight = (MyRenderLight)renderObject; renderLight.ShadowIgnoreObjects.Clear(); } break; } case MyRenderMessageEnum.UpdateRenderEnvironment: { var rMessage = (MyRenderMessageUpdateRenderEnvironment)message; float DX9Rescaling = 0.1195f; Sun.Direction = rMessage.SunDirection; Sun.Color = rMessage.SunColor; Sun.BackColor = rMessage.AdditionalSunColors[0]; Sun.BackIntensity = rMessage.AdditionalSunIntensities[0] * DX9Rescaling; Sun.Intensity = rMessage.SunIntensity; Sun.LightOn = rMessage.SunLightOn; Sun.SpecularColor = rMessage.SunSpecularColor; Sun.SunSizeMultiplier = rMessage.SunSizeMultiplier; Sun.DistanceToSun = rMessage.DistanceToSun; MyRender.AmbientColor = rMessage.AmbientColor; MyRender.AmbientMultiplier = rMessage.AmbientMultiplier; MyRender.EnvAmbientIntensity = rMessage.EnvAmbientIntensity; MyBackgroundCube.Filename = rMessage.BackgroundTexture; MyBackgroundCube.BackgroundColor = rMessage.BackgroundColor; MyBackgroundCube.BackgroundOrientation = rMessage.BackgroundOrientation; Sun.SunMaterial = rMessage.SunMaterial; MyBackgroundCube.Static.ReloadContent(); break; } #endregion #region Post processes case MyRenderMessageEnum.UpdateHDRSettings: { var rMessage = (MyRenderMessageUpdateHDRSettings)message; MyPostProcessHDR postProcessHDR = MyRender.GetPostProcess(MyPostProcessEnum.HDR) as MyPostProcessHDR; postProcessHDR.Enabled = rMessage.Enabled; postProcessHDR.Exposure = rMessage.Exposure; postProcessHDR.Threshold = rMessage.Threshold; postProcessHDR.BloomIntensity = rMessage.BloomIntensity; postProcessHDR.BloomIntensityBackground = rMessage.BloomIntensityBackground; postProcessHDR.VerticalBlurAmount = rMessage.VerticalBlurAmount; postProcessHDR.HorizontalBlurAmount = rMessage.HorizontalBlurAmount; postProcessHDR.NumberOfBlurPasses = rMessage.NumberOfBlurPasses; break; } case MyRenderMessageEnum.UpdateAntiAliasSettings: { var rMessage = (MyRenderMessageUpdateAntiAliasSettings)message; var postProcess = MyRender.GetPostProcess(MyPostProcessEnum.FXAA) as MyPostProcessAntiAlias; postProcess.Enabled = rMessage.Enabled; break; } case MyRenderMessageEnum.UpdateVignettingSettings: { var rMessage = (MyRenderMessageUpdateVignettingSettings)message; var postProcess = MyRender.GetPostProcess(MyPostProcessEnum.Vignetting) as MyPostProcessVignetting; postProcess.Enabled = rMessage.Enabled; postProcess.VignettingPower = rMessage.VignettingPower; break; } case MyRenderMessageEnum.UpdateColorMappingSettings: { var rMessage = (MyRenderMessageUpdateColorMappingSettings)message; var postProcess = MyRender.GetPostProcess(MyPostProcessEnum.ColorMapping) as MyPostProcessColorMapping; postProcess.Enabled = rMessage.Enabled; break; } case MyRenderMessageEnum.UpdateContrastSettings: { var rMessage = (MyRenderMessageUpdateContrastSettings)message; var postProcess = MyRender.GetPostProcess(MyPostProcessEnum.Contrast) as MyPostProcessContrast; postProcess.Enabled = rMessage.Enabled; postProcess.Contrast = rMessage.Contrast; postProcess.Hue = rMessage.Hue; postProcess.Saturation = rMessage.Saturation; break; } case MyRenderMessageEnum.UpdateChromaticAberrationSettings: { var rMessage = (MyRenderMessageUpdateChromaticAberrationSettings)message; var postProcess = MyRender.GetPostProcess(MyPostProcessEnum.ChromaticAberration) as MyPostProcessChromaticAberration; postProcess.Enabled = rMessage.Enabled; postProcess.DistortionLens = rMessage.DistortionLens; postProcess.DistortionCubic = rMessage.DistortionCubic; postProcess.DistortionWeights = rMessage.DistortionWeights; break; } case MyRenderMessageEnum.UpdateSSAOSettings: { var rMessage = (MyRenderMessageUpdateSSAOSettings)message; var postProcess = MyRender.GetPostProcess(MyPostProcessEnum.VolumetricSSAO2) as MyPostProcessVolumetricSSAO2; postProcess.Enabled = rMessage.Enabled; postProcess.ShowOnlySSAO = rMessage.ShowOnlySSAO; postProcess.UseBlur = rMessage.UseBlur; postProcess.MinRadius = rMessage.MinRadius; postProcess.MaxRadius = rMessage.MaxRadius; postProcess.RadiusGrowZScale = rMessage.RadiusGrowZScale; postProcess.CameraZFar = rMessage.CameraZFar; postProcess.Bias = rMessage.Bias; postProcess.Falloff = rMessage.Falloff; postProcess.NormValue = rMessage.NormValue; postProcess.Contrast = rMessage.Contrast; break; } case MyRenderMessageEnum.UpdateFogSettings: { var rMessage = (MyRenderMessageUpdateFogSettings)message; var postProcess = MyRender.GetPostProcess(MyPostProcessEnum.VolumetricFog) as MyPostProcessVolumetricFog; postProcess.Enabled = rMessage.Settings.Enabled; FogProperties.FogNear = rMessage.Settings.FogNear; FogProperties.FogFar = rMessage.Settings.FogFar; FogProperties.FogMultiplier = rMessage.Settings.FogMultiplier; FogProperties.FogBacklightMultiplier = rMessage.Settings.FogBacklightMultiplier; FogProperties.FogColor = rMessage.Settings.FogColor; break; } case MyRenderMessageEnum.UpdateGodRaysSettings: { var rMessage = (MyRenderMessageUpdateGodRaysSettings)message; var postProcess = MyRender.GetPostProcess(MyPostProcessEnum.GodRays) as MyPostProcessGodRays; postProcess.Enabled = rMessage.Enabled; postProcess.Density = rMessage.Density; postProcess.Weight = rMessage.Weight; postProcess.Decay = rMessage.Decay; postProcess.Exposition = rMessage.Exposition; postProcess.ApplyBlur = rMessage.ApplyBlur; break; } #endregion #region Environment case MyRenderMessageEnum.UpdateEnvironmentMap: { EnqueueDrawMessage(message); break; } #endregion #region Video case MyRenderMessageEnum.PlayVideo: { var rMessage = (MyRenderMessagePlayVideo)message; MyRender.PlayVideo(rMessage.ID, rMessage.VideoFile, rMessage.Volume); break; } case MyRenderMessageEnum.UpdateVideo: { var rMessage = (MyRenderMessageUpdateVideo)message; MyRender.UpdateVideo(rMessage.ID); break; } case MyRenderMessageEnum.DrawVideo: { var rMessage = (MyRenderMessageDrawVideo)message; EnqueueDrawMessage(rMessage); break; } case MyRenderMessageEnum.CloseVideo: { var rMessage = (MyRenderMessageCloseVideo)message; MyRender.CloseVideo(rMessage.ID); break; } case MyRenderMessageEnum.SetVideoVolume: { var rMessage = (MyRenderMessageSetVideoVolume)message; MyRender.SetVideoVolume(rMessage.ID, rMessage.Volume); break; } #endregion #region Secondary camera case MyRenderMessageEnum.DrawSecondaryCamera: { var rMessage = (MyRenderMessageDrawSecondaryCamera)message; EnqueueDrawMessage(rMessage); break; } case MyRenderMessageEnum.DrawSecondaryCameraSprite: { var rMessage = (MyRenderMessageDrawSecondaryCameraSprite)message; EnqueueDrawMessage(rMessage); break; } #endregion #region Decals case MyRenderMessageEnum.CreateDecal: { var rMessage = (MyRenderMessageCreateDecal)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ID, out renderObject)) { MyDecals.AddDecal( renderObject, ref rMessage.Triangle, rMessage.TrianglesToAdd, rMessage.Texture, (Vector3D)rMessage.Position, rMessage.LightSize, rMessage.Emissivity ); } break; } case MyRenderMessageEnum.HideDecals: { var rMessage = (MyRenderMessageHideDecals)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.ID, out renderObject)) { if (rMessage.Radius == 0 && renderObject is MyRenderTransformObject) { MyDecals.RemoveModelDecals(renderObject as MyRenderTransformObject); } else { if (renderObject is MyRenderVoxelCell) { VRageMath.BoundingSphere bs = new VRageMath.BoundingSphere(rMessage.Center, rMessage.Radius); MyDecals.HideTrianglesAfterExplosion(renderObject as MyRenderVoxelCell, ref bs); } } } break; } #endregion #region Cockpit case MyRenderMessageEnum.UpdateCockpitGlass: { var rMessage = (MyRenderMessageUpdateCockpitGlass)message; MyCockpitGlass.Visible = rMessage.Visible; MyCockpitGlass.PlayerHeadForCockpitInteriorWorldMatrix = (MatrixD)rMessage.WorldMatrix; MyCockpitGlass.GlassDirtAlpha = rMessage.DirtAlpha; MyCockpitGlass.Model = rMessage.Model; break; } #endregion #region Billboards and quality case MyRenderMessageEnum.UpdateBillboardsColorize: { var rMessage = (MyRenderMessageUpdateBillboardsColorize)message; EnqueueDrawMessage(rMessage); break; } case MyRenderMessageEnum.AddLineBillboardLocal: { var rMessage = (MyRenderMessageAddLineBillboardLocal)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.RenderObjectID, out renderObject)) { renderObject.Billboards.Add(rMessage); } break; } case MyRenderMessageEnum.AddPointBillboardLocal: { var rMessage = (MyRenderMessageAddPointBillboardLocal)message; MyRenderObject renderObject; if (m_renderObjects.TryGetValue(rMessage.RenderObjectID, out renderObject)) { renderObject.Billboards.Add(rMessage); } break; } case MyRenderMessageEnum.UpdateDistantImpostors: { var rMessage = (MyRenderMessageUpdateDistantImpostors)message; MyDistantImpostors.ImpostorProperties = rMessage.ImpostorProperties; MyDistantImpostors.Static.ReloadContent(); break; } case MyRenderMessageEnum.SetTextureIgnoreQuality: { var rMessage = (MyRenderMessageSetTextureIgnoreQuality)message; MyTextureManager.TexturesWithIgnoredQuality.Add(rMessage.Path); MyTextureManager.UnloadTexture(rMessage.Path); break; } case MyRenderMessageEnum.UpdateRenderQuality: { var rMessage = (MyRenderMessageUpdateRenderQuality)message; MyRenderQualityProfile profile = MyRenderConstants.m_renderQualityProfiles[(int)rMessage.RenderQuality]; profile.EnableCascadeBlending = rMessage.EnableCascadeBlending; MyRenderTexturePool.RenderQualityChanged(rMessage.RenderQuality); break; } case MyRenderMessageEnum.TakeScreenshot: { var rMessage = (MyRenderMessageTakeScreenshot)message; m_screenshot = new MyScreenshot(rMessage.SizeMultiplier, rMessage.PathToSave, rMessage.IgnoreSprites, rMessage.ShowNotification); ScreenshotOnlyFinal = !rMessage.Debug; //Will do before draw //UpdateScreenSize(); //MyEnvironmentMap.Reset(); break; } case MyRenderMessageEnum.RenderColoredTexture: { var rMessage = (MyRenderMessageRenderColoredTexture)message; m_texturesToRender.AddRange(rMessage.texturesToRender); break; } #endregion #region Characters case MyRenderMessageEnum.SetCharacterSkeleton: { var rMessage = (MyRenderMessageSetCharacterSkeleton)message; MyRenderObject renderCharacterObject; if (m_renderObjects.TryGetValue(rMessage.CharacterID, out renderCharacterObject)) { MyRenderCharacter renderCharacter = (MyRenderCharacter)renderCharacterObject; renderCharacter.SetSkeleton(rMessage.SkeletonBones, rMessage.SkeletonIndices); } break; } case MyRenderMessageEnum.SetCharacterTransforms: { var rMessage = (MyRenderMessageSetCharacterTransforms)message; MyRenderObject renderCharacterObject; if (m_renderObjects.TryGetValue(rMessage.CharacterID, out renderCharacterObject)) { MyRenderCharacter renderCharacter = (MyRenderCharacter)renderCharacterObject; renderCharacter.SetAnimationBones(rMessage.RelativeBoneTransforms); } break; } #endregion #region Debug draw case MyRenderMessageEnum.DebugDrawLine3D: case MyRenderMessageEnum.DebugDrawLine2D: case MyRenderMessageEnum.DebugDrawSphere: case MyRenderMessageEnum.DebugDrawAABB: case MyRenderMessageEnum.DebugDrawAxis: case MyRenderMessageEnum.DebugDrawOBB: case MyRenderMessageEnum.DebugDrawTriangle: case MyRenderMessageEnum.DebugDrawCapsule: case MyRenderMessageEnum.DebugDrawText2D: case MyRenderMessageEnum.DebugDrawText3D: case MyRenderMessageEnum.DebugDrawModel: case MyRenderMessageEnum.DebugDrawTriangles: case MyRenderMessageEnum.DebugDrawPlane: case MyRenderMessageEnum.DebugDrawCylinder: case MyRenderMessageEnum.DebugWaitForPresent: { EnqueueDebugDrawMessage(message); } break; case MyRenderMessageEnum.DebugCrashRenderThread: { throw new InvalidOperationException("Forced exception"); } #endregion #region Fonts and text case MyRenderMessageEnum.CreateFont: { var createFontMessage = message as MyRenderMessageCreateFont; Debug.Assert(createFontMessage != null); var renderFont = new MyRenderFont(createFontMessage.FontPath); renderFont.LoadContent(); AddFont(createFontMessage.FontId, renderFont, createFontMessage.IsDebugFont); break; } case MyRenderMessageEnum.DrawString: { EnqueueDrawMessage(message); break; } #endregion case MyRenderMessageEnum.VideoAdaptersRequest: { MyRenderProxy.SendVideoAdapters(GetAdaptersList()); break; } case MyRenderMessageEnum.SwitchDeviceSettings: { MyRenderProxy.RenderThread.SwitchSettings((message as MyRenderMessageSwitchDeviceSettings).Settings); break; } case MyRenderMessageEnum.SwitchRenderSettings: { // Dx9 Only understands interpolation and render quality. var rMessage = (MyRenderMessageSwitchRenderSettings)message; MyRenderProxy.Settings.EnableObjectInterpolation = rMessage.Settings.InterpolationEnabled; MyRenderProxy.Settings.EnableCameraInterpolation = rMessage.Settings.InterpolationEnabled; MyRenderProxy.RenderThread.SwitchQuality(rMessage.Settings.Dx9Quality); break; } case MyRenderMessageEnum.UnloadData: { MyRender.UnloadData(); break; } case MyRenderMessageEnum.CollectGarbage: { GC.Collect(); break; } case MyRenderMessageEnum.UpdatePostprocessSettings: { break; } default: // System.Diagnostics.Debug.Assert(false, "Unknown message"); break; } }
internal void AddSphereRing(BoundingSphere sphere, Color color, Matrix onb) { float increment = 1.0f / 32; for (float i=0; i < 1; i += increment) { float a0 = 2* (float)Math.PI * i; float a1 = 2* (float)Math.PI * (i + increment); Add( Vector3.Transform(new Vector3(Math.Cos(a0), 0, Math.Sin(a0)) * sphere.Radius, onb) + sphere.Center, Vector3.Transform(new Vector3(Math.Cos(a1), 0, Math.Sin(a1)) * sphere.Radius, onb) + sphere.Center, color); } }
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]; Vector4I[] boneIndices = (Vector4I[])tagData[MyImporterConstants.TAG_BLENDINDICES]; Vector4[] boneWeights = (Vector4[])tagData[MyImporterConstants.TAG_BLENDWEIGHTS]; if (boneIndices != null && boneIndices.Length != 0) { if (boneWeights != null && boneIndices.Length == boneWeights.Length && boneIndices.Length == m_vertices.Length) { m_bonesIndicesWeights = new MyCompressedBoneIndicesWeights[boneIndices.Length]; for (int it = 0; it < boneIndices.Length; it++) { m_bonesIndicesWeights[it].Indices = new Byte4(boneIndices[it].X, boneIndices[it].Y, boneIndices[it].Z, boneIndices[it].W); m_bonesIndicesWeights[it].Weights = new HalfVector4(boneWeights[it]); } } else { Debug.Assert(false, "Bone indices/weights my be same number as vertices"); } } 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("UseChannelTextures: " + (bool)tagData[MyImporterConstants.TAG_USE_CHANNEL_TEXTURES], LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("BoundingBox: " + BoundingBox, LoggingOptions.LOADING_MODELS); MyLog.Default.WriteLine("BoundingSphere: " + BoundingSphere, LoggingOptions.LOADING_MODELS); VRageRender.Utils.Stats.PerAppLifetime.MyModelsCount++; VRageRender.Utils.Stats.PerAppLifetime.MyModelsMeshesCount += m_meshContainer.Count; VRageRender.Utils.Stats.PerAppLifetime.MyModelsVertexesCount += GetVerticesCount(); VRageRender.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(); } }
/// <summary> /// Checks whether the current BoundingBox intersects a BoundingSphere. /// </summary> /// <param name="sphere">The BoundingSphere to check for intersection with.</param> public bool Intersects(BoundingSphere sphere) { return(Intersects(ref sphere)); }
public BoundingBox Include(BoundingSphere sphere) { return(Include(ref sphere)); }