//internal static void AttachHemisphericalLightInfo(LightId light, ref MyHemisphericalLightInfo info) //{ //} internal static void Update() { if (DirtyPointlights.Count > 0) { foreach (var id in DirtyPointlights) { var proxy = Pointlights[id.Index].BvhProxyId; var position = Lights.Data[id.Index].Position; var range = Pointlights[id.Index].Range; var aabb = new BoundingBox(position - range, position + range); Pointlights[id.Index].BvhProxyId = UpdateBvh(PointlightsBvh, id, Pointlights[id.Index].Enabled, proxy, ref aabb); Pointlights[id.Index].LastBvhUpdatePosition = position; } DirtyPointlights.Clear(); } if (DirtySpotlights.Count > 0) { foreach (var id in DirtySpotlights) { var proxy = Spotlights[id.Index].BvhProxyId; var position = Lights.Data[id.Index].Position; var range = Spotlights[id.Index].Range; var aabb = MakeAabbFromSpotlightCone(ref Spotlights[id.Index], position); Spotlights[id.Index].BvhProxyId = UpdateBvh(SpotlightsBvh, id, Spotlights[id.Index].Enabled, proxy, ref aabb); Spotlights[id.Index].LastBvhUpdatePosition = position; } DirtySpotlights.Clear(); } }
internal void SetAabb(BoundingBox aabb) { Aabb = aabb; for (int i = 0; i < m_components.Count; i++) { m_components[i].OnAabbChange(); } }
internal void SetLocalAabb(BoundingBox localAabb) { m_localAabb = localAabb; Aabb = m_localAabb.Value.Transform(WorldMatrix); for (int i = 0; i < m_components.Count; i++) { m_components[i].OnAabbChange(); } }
internal static BoundingBox MakeAabbFromSpotlightCone(ref MySpotlightInfo spotlight, Vector3 position) { float ratio = (float)Math.Sqrt(1 - spotlight.ApertureCos * spotlight.ApertureCos) / spotlight.ApertureCos; float h = ratio * spotlight.Range; var bb = BoundingBox.CreateInvalid(); bb.Include(new Vector3(-h, -h, 0)); bb.Include(new Vector3(h, h, -spotlight.Range)); return(bb.Transform(Matrix.CreateLookAtInv(position, position + spotlight.Direction, spotlight.Up))); }
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); }
internal void UpdateBeforeDraw() { if (m_dirtyProxy) { RebuildProxies(); } foreach (var val in m_materialGroups.Values) { var index = val.m_index; val.UpdateProxyVerticesNum(ref m_proxy.Proxies[index]); } if (m_dirtyPosition) { foreach (var val in m_materialGroups.Values) { val.UpdateAll(); } m_dirtyPosition = false; } if (m_dirtyTree) { BoundingBox bb = BoundingBox.CreateInvalid(); foreach (var child in m_children) { if (child.m_visible && child.GetRenderable() != null && !child.GetRenderable().IsRendered) { bb.Include(child.Aabb); } } m_owner.Aabb = bb; if (m_materialGroups.Count > 0) { if (m_btreeProxy == -1) { m_btreeProxy = MyScene.GroupsDBVH.AddProxy(ref m_owner.Aabb, m_proxy, 0); } else { MyScene.GroupsDBVH.MoveProxy(m_btreeProxy, ref m_owner.Aabb, Vector3.Zero); } } m_dirtyTree = false; } }
internal void Construct() { m_components.Clear(); m_visible = true; m_renderProxyDirty = true; m_ID = new MyIDTracker <MyActor>(); m_localAabb = null; m_relativeTransform = null; Aabb = BoundingBox.CreateInvalid(); }
internal void Construct() { m_components.Clear(); m_visible = true; m_renderProxyDirty = true; m_ID = new MyIDTracker<MyActor>(); m_localAabb = null; m_relativeTransform = null; Aabb = BoundingBox.CreateInvalid(); }
//internal static void AttachHemisphericalLightInfo(LightId light, ref MyHemisphericalLightInfo info) //{ //} internal static void Update() { // touch all lights again, because they don't get updated always when parent is foreach (var light in IdIndex.Values) { var position = light.LocalPosition; var gid = light.ParentGID; if (gid != -1 && MyIDTracker <MyActor> .FindByID((uint)gid) != null) { var matrix = MyIDTracker <MyActor> .FindByID((uint)gid).WorldMatrix; Vector3.Transform(ref position, ref matrix, out position); } Lights.Data[light.Index].Position = position; } if (DirtyPointlights.Count > 0) { foreach (var id in DirtyPointlights) { var proxy = Pointlights[id.Index].BvhProxyId; var position = Lights.Data[id.Index].Position; var range = Pointlights[id.Index].Range; var aabb = new BoundingBox(position - range, position + range); Pointlights[id.Index].BvhProxyId = UpdateBvh(PointlightsBvh, id, Pointlights[id.Index].Enabled, proxy, ref aabb); Pointlights[id.Index].LastBvhUpdatePosition = position; } DirtyPointlights.Clear(); } if (DirtySpotlights.Count > 0) { foreach (var id in DirtySpotlights) { var proxy = Spotlights[id.Index].BvhProxyId; var position = Lights.Data[id.Index].Position; var range = Spotlights[id.Index].Range; var aabb = MakeAabbFromSpotlightCone(ref Spotlights[id.Index], position); Spotlights[id.Index].BvhProxyId = UpdateBvh(SpotlightsBvh, id, Spotlights[id.Index].Enabled, proxy, ref aabb); Spotlights[id.Index].LastBvhUpdatePosition = position; } DirtySpotlights.Clear(); } }
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; } }
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)); }
internal void SetMatrix(ref Matrix matrix) { WorldMatrix = matrix; if (m_localAabb.HasValue) { Aabb = m_localAabb.Value.Transform(WorldMatrix); } // figure out final matrix for (int i = 0; i < m_components.Count; i++) { m_components[i].OnMatrixChange(); } if (m_localAabb.HasValue) { for (int i = 0; i < m_components.Count; i++) { m_components[i].OnAabbChange(); } } }
static void SendOutputMessages() { foreach (var q in m_cullQuery.FrustumQuery) { foreach (var proxy in q.List) { // all should have same parent MyRenderProxy.VisibleObjectsWrite.Add(proxy.Proxies[0].Parent.m_owner.ID); } } // TODO: just for now foreach (var h in MyComponentFactory <MyGroupRootComponent> .GetAll()) { if (true) { BoundingBox bb = BoundingBox.CreateInvalid(); foreach (var child in h.m_children) { if (child.m_visible) { bb.Include(child.Aabb); } } if (MyEnvironment.ViewFrustum.Contains(bb) != VRageMath.ContainmentType.Disjoint) { MyRenderProxy.VisibleObjectsWrite.Add(h.m_owner.ID); } } } foreach (var id in MyClipmapFactory.ClipmapByID.Keys) { MyRenderProxy.VisibleObjectsWrite.Add(id); } }
// 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; } }
public static MyOrientedBoundingBox CreateFromBoundingBox(BoundingBox box) { Vector3 center = (Vector3)((box.Min + box.Max) * 0.5f); return(new MyOrientedBoundingBox(center, (Vector3)((box.Max - box.Min) * 0.5f), Quaternion.Identity)); }
public static void SetInstanceBuffer(uint entityId, uint instanceBufferId, int instanceStart, int instanceCount, BoundingBox entityLocalAabb) { var message = MessagePool.Get<MyRenderMessageSetInstanceBuffer>(MyRenderMessageEnum.SetInstanceBuffer); message.ID = entityId; message.InstanceBufferId = instanceBufferId; message.InstanceStart = instanceStart; message.InstanceCount = instanceCount; message.LocalAabb = entityLocalAabb; EnqueueMessage(message); }
public static void UpdateClipmapCell( uint clipmapId, MyCellCoord cell, List<MyClipmapCellBatch> batches, Vector3D positionOffset, Vector3 positionScale, BoundingBox meshAabb) { var message = MessagePool.Get<MyRenderMessageUpdateClipmapCell>(MyRenderMessageEnum.UpdateClipmapCell); Debug.Assert(message.Batches.Count == 0, "Message was not properly cleared"); message.ClipmapId = clipmapId; message.Cell = cell; message.Batches.AddList(batches); message.PositionOffset = positionOffset; message.PositionScale = positionScale; message.MeshAabb = meshAabb; EnqueueMessage(message); }
//internal static void BeginQuadRendering() //{ // var context = MyRender.Context; // context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; // context.Rasterizer.SetViewport(0, 0, MyRender.ViewportResolution.X, MyRender.ViewportResolution.Y); // context.OutputMerger.SetTargets(null as DepthStencilView, MyRender.Backbuffer.RenderTarget); // context.OutputMerger.BlendState = null; //} //internal static void DrawQuad() //{ //} internal static void DrawHierarchyDebug() { var worldToClip = MyEnvironment.ViewProjection; var displayString = new StringBuilder(); var batch = MyLinesRenderer.CreateBatch(); if (MyRender11.Settings.DisplayIDs) { foreach (var actor in MyActorFactory.GetAll()) { var h = actor.GetGroupLeaf(); var r = actor.GetRenderable(); Vector3 position; uint ID; if (r != null) { position = r.m_owner.WorldMatrix.Translation; ID = r.m_owner.ID; } else if (h != null) { position = h.m_owner.WorldMatrix.Translation; ID = h.m_owner.ID; } else { continue; } var clipPosition = Vector3.Transform(position, ref worldToClip); clipPosition.X = clipPosition.X * 0.5f + 0.5f; clipPosition.Y = clipPosition.Y * -0.5f + 0.5f; if (clipPosition.Z > 0 && clipPosition.Z < 1) { displayString.AppendFormat("{0}", ID); MySpritesRenderer.DrawText(new Vector2(clipPosition.X, clipPosition.Y) * MyRender11.ViewportResolution, displayString, Color.DarkCyan, 0.5f); } displayString.Clear(); } } if (MyRender11.Settings.DisplayAabbs) { //foreach (var h in MyComponentFactory<MyHierarchyComponent>.GetAll()) //{ // if (h.IsParent) // { // batch.AddBoundingBox(h.m_owner.Aabb, Color.Red); // } // else // { // batch.AddBoundingBox(h.m_owner.Aabb, Color.Orange); // } //} foreach (var actor in MyActorFactory.GetAll()) { var h = actor.GetGroupRoot(); var r = actor.GetRenderable(); if (h != null) { BoundingBox bb = BoundingBox.CreateInvalid(); foreach (var child in h.m_children) { if (child.m_visible) { bb.Include(child.Aabb); } } batch.AddBoundingBox(bb, Color.Red); MyPrimitivesRenderer.Draw6FacedConvex(bb.GetCorners(), Color.Red, 0.1f); } else if (r != null && actor.GetGroupLeaf() == null) { batch.AddBoundingBox(r.m_owner.Aabb, Color.Green); } } } batch.Commit(); }
internal static int UpdateBvh(MyDynamicAABBTree bvh, LightId lid, bool enabled, int proxy, ref BoundingBox aabb) { if(enabled && proxy == -1) { return bvh.AddProxy(ref aabb, lid, 0); } else if(enabled && proxy != -1) { bvh.MoveProxy(proxy, ref aabb, Vector3.Zero); return proxy; } else { bvh.RemoveProxy(proxy); } return -1; }
//internal static void AttachHemisphericalLightInfo(LightId light, ref MyHemisphericalLightInfo info) //{ //} internal static void Update() { // touch all lights again, because they don't get updated always when parent is foreach (var light in IdIndex.Values) { var position = light.LocalPosition; var gid = light.ParentGID; if (gid != -1 && MyIDTracker<MyActor>.FindByID((uint)gid) != null) { var matrix = MyIDTracker<MyActor>.FindByID((uint)gid).WorldMatrix; Vector3.Transform(ref position, ref matrix, out position); } Lights.Data[light.Index].Position = position; } if(DirtyPointlights.Count > 0) { foreach(var id in DirtyPointlights) { var proxy = Pointlights[id.Index].BvhProxyId; var position = Lights.Data[id.Index].Position; var range = Pointlights[id.Index].Range; var aabb = new BoundingBox(position - range, position + range); Pointlights[id.Index].BvhProxyId = UpdateBvh(PointlightsBvh, id, Pointlights[id.Index].Enabled, proxy, ref aabb); Pointlights[id.Index].LastBvhUpdatePosition = position; } DirtyPointlights.Clear(); } if (DirtySpotlights.Count > 0) { foreach (var id in DirtySpotlights) { var proxy = Spotlights[id.Index].BvhProxyId; var position = Lights.Data[id.Index].Position; var range = Spotlights[id.Index].Range; var aabb = MakeAabbFromSpotlightCone(ref Spotlights[id.Index], position); Spotlights[id.Index].BvhProxyId = UpdateBvh(SpotlightsBvh, id, Spotlights[id.Index].Enabled, proxy, ref aabb); Spotlights[id.Index].LastBvhUpdatePosition = position; } DirtySpotlights.Clear(); } }
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(); } }
internal static int UpdateBvh(MyDynamicAABBTree bvh, LightId lid, bool enabled, int proxy, ref BoundingBox aabb) { if (enabled && proxy == -1) { return(bvh.AddProxy(ref aabb, lid, 0)); } else if (enabled && proxy != -1) { bvh.MoveProxy(proxy, ref aabb, Vector3.Zero); return(proxy); } else { bvh.RemoveProxy(proxy); } return(-1); }
// 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(); } }
internal void SetMatrix(ref Matrix matrix) { WorldMatrix = matrix; if (m_localAabb.HasValue) { Aabb = m_localAabb.Value.Transform(WorldMatrix); } // figure out final matrix for (int i = 0; i < m_components.Count; i++) m_components[i].OnMatrixChange(); if(m_localAabb.HasValue) { for (int i = 0; i < m_components.Count; i++) m_components[i].OnAabbChange(); } }
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(); } }
internal void SetLocalAabb(BoundingBox localAabb) { m_localAabb = localAabb; Aabb = m_localAabb.Value.Transform(WorldMatrix); for (int i = 0; i < m_components.Count; i++) m_components[i].OnAabbChange(); }
//internal static void AttachHemisphericalLightInfo(LightId light, ref MyHemisphericalLightInfo info) //{ //} internal static void Update() { if(DirtyPointlights.Count > 0) { foreach(var id in DirtyPointlights) { var proxy = Pointlights[id.Index].BvhProxyId; var position = Lights.Data[id.Index].Position; var range = Pointlights[id.Index].Range; var aabb = new BoundingBox(position - range, position + range); Pointlights[id.Index].BvhProxyId = UpdateBvh(PointlightsBvh, id, Pointlights[id.Index].Enabled, proxy, ref aabb); Pointlights[id.Index].LastBvhUpdatePosition = position; } DirtyPointlights.Clear(); } if (DirtySpotlights.Count > 0) { foreach (var id in DirtySpotlights) { var proxy = Spotlights[id.Index].BvhProxyId; var position = Lights.Data[id.Index].Position; var range = Spotlights[id.Index].Range; var aabb = MakeAabbFromSpotlightCone(ref Spotlights[id.Index], position); Spotlights[id.Index].BvhProxyId = UpdateBvh(SpotlightsBvh, id, Spotlights[id.Index].Enabled, proxy, ref aabb); Spotlights[id.Index].LastBvhUpdatePosition = position; } DirtySpotlights.Clear(); } }
internal void SetAabb(BoundingBox aabb) { Aabb = aabb; for (int i = 0; i < m_components.Count; i++) m_components[i].OnAabbChange(); }