示例#1
0
        static void UpdateActors()
        {
            ProfilerShort.Begin("UpdateActors");
            ProfilerShort.Begin("MyRenderableComponent rebuild dirty");
            Debug.Assert(m_pendingComponentsToRemove.Count == 0, "Temporary list not cleared after use");
            foreach (var renderableComponent in PendingComponentsToUpdate)
            {
                renderableComponent.RebuildRenderProxies();

                if (!renderableComponent.Owner.RenderDirty)
                {
                    m_pendingComponentsToRemove.Add(renderableComponent);
                }
            }

            foreach (var renderableComponent in m_pendingComponentsToRemove)
            {
                PendingComponentsToUpdate.Remove(renderableComponent);
            }
            m_pendingComponentsToRemove.Clear();


            ProfilerShort.BeginNextBlock("MyInstanceLodComponent OnFrameUpdate");
            foreach (var instanceLodComponent in MyComponentFactory <MyInstanceLodComponent> .GetAll())
            {
                instanceLodComponent.OnFrameUpdate();
            }
            ProfilerShort.End();
            ProfilerShort.End();
        }
示例#2
0
 internal static void DisposeGrass()
 {
     foreach (var f in MyComponentFactory <MyFoliageComponent> .GetAll())
     {
         f.Dispose();
     }
 }
示例#3
0
        internal static MyActor CreateVoxelCell()
        {
            var actor = Create();

            actor.AddComponent <MyRenderableComponent>(MyComponentFactory <MyVoxelRenderableComponent> .Create());
            return(actor);
        }
示例#4
0
        internal static MyActor CreateSceneObject2()
        {
            var actor = Create();

            actor.AddComponent <MyInstanceComponent>(MyComponentFactory <MyInstanceComponent> .Create());
            return(actor);
        }
示例#5
0
        private void UpdateFoliage(bool refresh = false)
        {
            var foliageComponent = m_actor.GetFoliage();

            bool removeComponent         = m_lod > MyFoliageComponent.LodLimit || !m_actor.IsVisible;
            bool shouldInitializeFoliage = false;

            if (refresh && foliageComponent != null)
            {
                foliageComponent.RefreshStreams();
            }

            if (foliageComponent == null && !removeComponent)
            {
                shouldInitializeFoliage = m_mesh.ShouldHaveFoliage();
            }

            if (shouldInitializeFoliage)
            {
                m_actor.AddComponent <MyFoliageComponent>(MyComponentFactory <MyFoliageComponent> .Create());
            }
            else if (foliageComponent != null && removeComponent)
            {
                foliageComponent.InvalidateStreams();
                m_actor.RemoveComponent <MyFoliageComponent>(foliageComponent);
            }
        }
示例#6
0
        //internal static MyActor CreateCullObject()
        //{
        //    var actor = Create();
        //    actor.AddComponent(MyComponentFactory<MyHierarchyComponent>.Create());
        //    return actor;
        //}

        internal static MyActor CreateGroup()
        {
            var actor = Create();

            actor.AddComponent(MyComponentFactory <MyGroupRootComponent> .Create());
            return(actor);
        }
示例#7
0
        private static void SendGlobalOutputMessages()
        {
            ProfilerShort.Begin("SendGlobalOutputMessages");
            ProfilerShort.Begin("Root");
            foreach (var groupRootComponent in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                if (true)
                {
                    BoundingBoxD bb = BoundingBoxD.CreateInvalid();

                    foreach (var child in groupRootComponent.m_children)
                    {
                        if (child.IsVisible)
                        {
                            bb.Include(child.Aabb);
                        }
                    }

                    if (MyRender11.Environment.ViewFrustumClippedD.Contains(bb) != VRageMath.ContainmentType.Disjoint)
                    {
                        MyRenderProxy.VisibleObjectsWrite.Add(groupRootComponent.Owner.ID);
                    }
                }
            }

            ProfilerShort.BeginNextBlock("Clipmap");
            foreach (var id in MyClipmapFactory.ClipmapByID.Keys)
            {
                MyRenderProxy.VisibleObjectsWrite.Add(id);
            }
            ProfilerShort.End();
            ProfilerShort.End();
        }
 internal static void ClearInvalidInstances(InstancingId id)
 {
     foreach (var component in MyComponentFactory <MyInstanceLodComponent> .GetAll())
     {
         component.ClearInstances(id);
     }
 }
示例#9
0
        internal static MyActor CreateSceneObject()
        {
            var actor = Create();

            actor.AddComponent(MyComponentFactory <MyRenderableComponent> .Create());
            return(actor);
        }
示例#10
0
        internal static void OnDeviceReset()
        {
            MyHwBuffers.OnDeviceReset();
            MyShaders.OnDeviceReset();
            MyMaterialShaders.OnDeviceReset();
            MyPipelineStates.OnDeviceReset();
            MyTextures.OnDeviceReset();
            MyRwTextures.OnDeviceReset();
            MyTransparentRendering.OnDeviceReset();

            ResetShadows(Settings.ShadowCascadeCount, RenderSettings.ShadowQuality.ShadowCascadeResolution());

            MyBillboardRenderer.OnDeviceRestart();
            MyScreenDecals.OnDeviceReset();

            MyMeshMaterials1.InvalidateMaterials();
            MyVoxelMaterials1.InvalidateMaterials();

            MyRenderableComponent.MarkAllDirty();
            foreach (var f in MyComponentFactory <MyFoliageComponent> .GetAll())
            {
                f.Dispose();
            }

            foreach (var c in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                c.OnDeviceReset();
            }

            MyBigMeshTable.Table.OnDeviceReset();
            MySceneMaterials.OnDeviceReset();
            MyMeshes.OnDeviceReset();
            MyInstancing.OnDeviceReset();
            MyScreenDecals.OnDeviceReset();
        }
示例#11
0
        private static void OnDeviceReset()
        {
            MyManagers.OnDeviceReset();

            MyShaders.OnDeviceReset();
            MyMaterialShaders.OnDeviceReset();

            MyTransparentRendering.OnDeviceReset();

            ResetShadows(MyShadowCascades.Settings.NewData.CascadesCount, Settings.User.ShadowQuality.ShadowCascadeResolution());

            MyBillboardRenderer.OnDeviceReset();
            MyScreenDecals.OnDeviceReset();

            MyMeshMaterials1.OnDeviceReset();
            MyVoxelMaterials1.OnDeviceReset();

            MyRenderableComponent.MarkAllDirty();
            foreach (var f in MyComponentFactory <MyFoliageComponent> .GetAll())
            {
                f.Dispose();
            }

            foreach (var c in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                c.OnDeviceReset();
            }

            MyBigMeshTable.Table.OnDeviceReset();
            MySceneMaterials.OnDeviceReset();
            MyMeshes.OnDeviceReset();
            MyInstancing.OnDeviceReset();
            MyScreenDecals.OnDeviceReset();
        }
示例#12
0
        internal static void OnDeviceReset()
        {
            MyHwBuffers.OnDeviceReset();
            MyShaders.OnDeviceReset();
            MyMaterialShaders.OnDeviceReset();
            MyPipelineStates.OnDeviceReset();
            MyTextures.OnDeviceReset();
            MyRwTextures.OnDeviceEnd();
            MyShadows.OnDeviceReset();
            MyBillboardRenderer.OnDeviceRestart();

            MyMeshMaterials1.InvalidateMaterials();
            MyVoxelMaterials1.InvalidateMaterials();

            MyRenderableComponent.MarkAllDirty();
            foreach (var f in MyComponentFactory <MyFoliageComponent> .GetAll())
            {
                f.Dispose();
            }

            foreach (var c in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                c.OnDeviceReset();
            }

            MyBigMeshTable.Table.OnDeviceReset();
            MySceneMaterials.OnDeviceReset();
            MyMeshes.OnDeviceReset();
            MyInstancing.OnDeviceReset();
        }
示例#13
0
        internal static MyActor CreateCharacter()
        {
            var actor = Create();

            actor.AddComponent(MyComponentFactory <MyRenderableComponent> .Create());
            actor.AddComponent(MyComponentFactory <MySkinningComponent> .Create());
            return(actor);
        }
示例#14
0
 internal static MyActor GetInstanceActor(MyRenderableComponent original)
 {
     if (m_instanceActor == null)
     {
         m_instanceActor = MyActorFactory.Create();
         m_instanceActor.AddComponent <MyInstanceLodComponent>(MyComponentFactory <MyInstanceLodComponent> .Create());
     }
     return(m_instanceActor);
 }
 static void UpdateActors()
 {
     foreach (var renderable in MyComponentFactory <MyRenderableComponent> .GetAll())
     {
         if (renderable.IsVisible)
         {
             renderable.OnFrameUpdate();
         }
     }
 }
        private static void UpdateSceneFrame()
        {
            MySimpleProfiler.Begin("Textures");
            ProfilerShort.Begin("LoadMeshes");
            MyMeshes.Load();
            ProfilerShort.End();

            ProfilerShort.Begin("QueryTexturesFromEntities");
            QueryTexturesFromEntities();
            ProfilerShort.End();
            ProfilerShort.Begin("MyTextures.Load");
            MyManagers.FileTextures.LoadAllRequested();
            ProfilerShort.End();
            ProfilerShort.Begin("GatherTextures");
            GatherTextures();
            ProfilerShort.End();
            MySimpleProfiler.End("Textures");

            MyBillboardRenderer.OnFrameStart();

            UpdateActors();

            MyBigMeshTable.Table.MoveToGPU();

            ProfilerShort.Begin("Update merged groups");
            ProfilerShort.Begin("UpdateBeforeDraw");
            foreach (var r in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                r.UpdateBeforeDraw();
            }
            ProfilerShort.End();

            ProfilerShort.Begin("MoveToGPU");
            foreach (var r in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                foreach (var val in r.m_materialGroups.Values)
                {
                    // optimize: keep list+set for updating
                    val.MoveToGPU();
                }
            }
            ProfilerShort.End();
            ProfilerShort.End();

            ProfilerShort.Begin("Fill foliage streams");
            MyGpuProfiler.IC_BeginBlock("Fill foliage streams");
            m_foliageGenerator.PerFrame();
            m_foliageGenerator.Begin();
            MyFoliageComponents.Update();
            m_foliageGenerator.End();
            MyGpuProfiler.IC_EndBlock();
            ProfilerShort.End();

            MyCommon.MoveToNextFrame();
        }
示例#17
0
        internal static void Deallocate(this MyActorComponent item)
        {
            var voxelRenderable = item as MyVoxelRenderableComponent; // TODO: Rewrite this whole method

            if (voxelRenderable != null)
            {
                MyComponentFactory <MyVoxelRenderableComponent> .Deallocate(voxelRenderable);

                return;
            }

            switch (item.Type)
            {
            case MyActorComponentEnum.Renderable:
                MyComponentFactory <MyRenderableComponent> .Deallocate(item as MyRenderableComponent);

                break;

            case MyActorComponentEnum.Instancing:
                MyComponentFactory <MyInstancingComponent> .Deallocate(item as MyInstancingComponent);

                break;

            case MyActorComponentEnum.Skinning:
                MyComponentFactory <MySkinningComponent> .Deallocate(item as MySkinningComponent);

                break;

            case MyActorComponentEnum.Foliage:
                MyComponentFactory <MyFoliageComponent> .Deallocate(item as MyFoliageComponent);

                break;

            case MyActorComponentEnum.GroupLeaf:
                MyComponentFactory <MyGroupLeafComponent> .Deallocate(item as MyGroupLeafComponent);

                break;

            case MyActorComponentEnum.GroupRoot:
                MyComponentFactory <MyGroupRootComponent> .Deallocate(item as MyGroupRootComponent);

                break;

            case MyActorComponentEnum.InstanceLod:
                MyComponentFactory <MyInstanceLodComponent> .Deallocate(item as MyInstanceLodComponent);

                break;

            case MyActorComponentEnum.Unassigned:
                Debug.Assert(false, "Can't find component factory");
                break;
            }
        }
示例#18
0
        internal MyClipmapCellProxy(MyCellCoord cellCoord, ref VRageMath.MatrixD worldMatrix, RenderFlags additionalFlags = 0)
        {
            m_worldMatrix = worldMatrix;

            m_actor = MyActorFactory.CreateSceneObject();
            m_actor.SetMatrix(ref worldMatrix);
            m_actor.AddComponent(MyComponentFactory <MyFoliageComponent> .Create());

            m_lod = cellCoord.Lod;

            Mesh = MyMeshes.CreateVoxelCell(cellCoord.CoordInLod, cellCoord.Lod);
            m_actor.GetRenderable().SetModel(Mesh);
            m_actor.GetRenderable().m_additionalFlags = MyProxiesFactory.GetRenderableProxyFlags(additionalFlags);
        }
示例#19
0
        internal MyClipmapCellProxy(MyCellCoord cellCoord, ref VRageMath.MatrixD worldMatrix)
        {
            m_worldMatrix = worldMatrix;

            m_actor = MyActorFactory.CreateSceneObject();
            //m_mesh = new MyVoxelMesh(cellCoord.CoordInLod, cellCoord.Lod, "");
            //m_actor.GetRenderable().SetModel(m_mesh);
            m_actor.SetMatrix(ref worldMatrix);
            m_actor.AddComponent(MyComponentFactory <MyFoliageComponent> .Create());

            m_lod = cellCoord.Lod;

            Mesh = MyMeshes.CreateVoxelCell(cellCoord.CoordInLod, cellCoord.Lod);
            m_actor.GetRenderable().SetModel(Mesh);

            m_discardingOn = false;
        }
示例#20
0
        internal static void Deallocate(this MyActorComponent item)
        {
            switch (item.Type)
            {
            case MyActorComponentEnum.Renderable:
                MyComponentFactory <MyRenderableComponent> .Deallocate(item as MyRenderableComponent);

                break;

            case MyActorComponentEnum.Instancing:
                MyComponentFactory <MyInstancingComponent> .Deallocate(item as MyInstancingComponent);

                break;

            case MyActorComponentEnum.Skinning:
                MyComponentFactory <MySkinningComponent> .Deallocate(item as MySkinningComponent);

                break;

            case MyActorComponentEnum.Foliage:
                MyComponentFactory <MyFoliageComponent> .Deallocate(item as MyFoliageComponent);

                break;

            case MyActorComponentEnum.GroupLeaf:
                MyComponentFactory <MyGroupLeafComponent> .Deallocate(item as MyGroupLeafComponent);

                break;

            case MyActorComponentEnum.GroupRoot:
                MyComponentFactory <MyGroupRootComponent> .Deallocate(item as MyGroupRootComponent);

                break;

            case MyActorComponentEnum.InstanceLod:
                MyComponentFactory <MyInstanceLodComponent> .Deallocate(item as MyInstanceLodComponent);

                break;

            case MyActorComponentEnum.Unassigned:
                Debug.Assert(false, "Can't find component factory");
                break;
            }
        }
        static void SendOutputMessages()
        {
            foreach (var q in m_cullQuery.FrustumQueries)
            {
                foreach (var proxy in q.List)
                {
                    // all should have same parent
                    if (proxy.Proxies.Length > 0)
                    {
                        MyRenderProxy.VisibleObjectsWrite.Add(proxy.Proxies[0].Parent.m_owner.ID);
                    }
                }
            }

            // TODO: just for now
            foreach (var h in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                if (true)
                {
                    BoundingBoxD bb = BoundingBoxD.CreateInvalid();

                    foreach (var child in h.m_children)
                    {
                        if (child.m_visible)
                        {
                            bb.Include(child.Aabb);
                        }
                    }

                    if (MyEnvironment.ViewFrustumClippedD.Contains(bb) != VRageMath.ContainmentType.Disjoint)
                    {
                        MyRenderProxy.VisibleObjectsWrite.Add(h.m_owner.ID);
                    }
                }
            }

            foreach (var id in MyClipmapFactory.ClipmapByID.Keys)
            {
                MyRenderProxy.VisibleObjectsWrite.Add(id);
            }
        }
示例#22
0
        internal static void Render()
        {
            m_instance.ViewProjection = MyEnvironment.ViewProjectionAt0;
            m_instance.Viewport       = new MyViewport(MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y);
            //m_instance.DepthBuffer = MyRender.MainGbuffer.DepthBuffer.DepthStencil;
            //m_instance.RTs = MyRender.MainGbuffer.GbufferTargets;

            m_instance.PerFrame();
            m_instance.Begin();

            var viewFrustum = new BoundingFrustumD(MyEnvironment.ViewProjectionD);

            foreach (var f in MyComponentFactory <MyFoliageComponent> .GetAll())
            {
                if (f.m_owner.CalculateCameraDistance() < MyRender11.RenderSettings.FoliageDetails.GrassDrawDistance() &&
                    viewFrustum.Contains(f.m_owner.Aabb) != VRageMath.ContainmentType.Disjoint)
                {
                    f.Render(m_instance);
                }
            }

            m_instance.End();
        }
        internal static void DrawSceneDebug()
        {
            //if(true)
            //{
            //    //m_proj = MyEnvironment.Projection;
            //    //m_vp = MyEnvironment.ViewProjection;
            //    //m_invvp = MyEnvironment.InvViewProjection;

            //    Vector2 groupDim = new Vector2(256, 256);
            //    Vector2 tileScale = new Vector2(1600, 900) / (2 * groupDim);
            //    Vector2 tileBias = tileScale - new Vector2(1, 1);


            //    //Vector4 c1 = new Vector4(m_proj.M11 * tileScale.X, 0, tileBias.X, 0);
            //    //Vector4 c2 = new Vector4(0, -m_proj.M22 * tileScale.Y, tileBias.Y, 0);
            //    Vector4 c1 = new Vector4(m_proj.M11, 0, 0, 0);
            //    Vector4 c2 = new Vector4(0, m_proj.M22, 0, 0);
            //    Vector4 c4 = new Vector4(0, 0, 1, 0);

            //    var frustumPlane0 = new VRageMath.Plane(c4 - c1);
            //    var frustumPlane1 = new VRageMath.Plane(c4 + c1);
            //    var frustumPlane2 = new VRageMath.Plane(c4 - c2);
            //    var frustumPlane3 = new VRageMath.Plane(c4 + c2);
            //    frustumPlane0.Normalize();
            //    frustumPlane1.Normalize();
            //    frustumPlane2.Normalize();
            //    frustumPlane3.Normalize();


            //    var ray0 = ComputeIntersectionLine(ref frustumPlane2, ref frustumPlane0);
            //    var ray1 = ComputeIntersectionLine(ref frustumPlane1, ref frustumPlane2);
            //    var ray2 = ComputeIntersectionLine(ref frustumPlane3, ref frustumPlane1);
            //    var ray3 = ComputeIntersectionLine(ref frustumPlane0, ref frustumPlane3);


            //    TransformRay(ref ray0, ref m_invvp);
            //    TransformRay(ref ray1, ref m_invvp);
            //    TransformRay(ref ray2, ref m_invvp);
            //    TransformRay(ref ray3, ref m_invvp);


            //    var batch = MyLinesRenderer.CreateBatch();

            //    batch.Add(ray0.Position, ray0.Position + ray0.Direction * 100, Color.Red);
            //    batch.Add(ray1.Position, ray1.Position + ray1.Direction * 100, Color.Red);
            //    batch.Add(ray2.Position, ray2.Position + ray2.Direction * 100, Color.Red);
            //    batch.Add(ray3.Position, ray3.Position + ray3.Direction * 100, Color.Red);

            //    batch.AddFrustum(new BoundingFrustum(m_vp), Color.Green);

            //    batch.Commit();

            //}

            // draw lights
            //if(false)
            //{
            //    MyLinesBatch batch = MyLinesRenderer.CreateBatch();

            //    foreach (var light in MyLight.Collection)
            //    {
            //        if (light.PointLightEnabled)
            //        {
            //            var position = light.GetPosition();
            //            //batch.AddBoundingBox(new BoundingBox(position - light.Pointlight.Range, position + light.Pointlight.Range), Color.Red);

            //            batch.AddSphereRing(new BoundingSphere(position, light.Pointlight.Range), new Color(light.Pointlight.Color), Matrix.Identity);
            //            batch.AddSphereRing(new BoundingSphere(position, light.Pointlight.Range), new Color(light.Pointlight.Color), Matrix.CreateRotationX((float)Math.PI * 0.5f));
            //            batch.AddSphereRing(new BoundingSphere(position, light.Pointlight.Range), new Color(light.Pointlight.Color), Matrix.CreateRotationZ((float)Math.PI * 0.5f));

            //            batch.AddSphereRing(new BoundingSphere(position, light.Pointlight.Radius), new Color(light.Pointlight.Color), Matrix.Identity);
            //            batch.AddSphereRing(new BoundingSphere(position, light.Pointlight.Radius), new Color(light.Pointlight.Color), Matrix.CreateRotationX((float)Math.PI * 0.5f));
            //        }
            //    }

            //    batch.Commit();
            //}

            //
            if (false)
            {
                MyLinesBatch batch = MyLinesRenderer.CreateBatch();

                foreach (var r in MyComponentFactory <MyRenderableComponent> .GetAll())
                {
                    if (r.Owner.GetInstanceLod() != null)
                    {
                        batch.AddBoundingBox((BoundingBox)r.Owner.Aabb, Color.Blue);
                    }
                }

                batch.Commit();
            }

            if (false)
            {
                MyLinesBatch batch = MyLinesRenderer.CreateBatch();
                //var radius = new [] { 0, 40, 72, 128, 256 , 512 };
                var   radius   = new[] { 0, 50, 80, 128, 256, 512 };
                float cellSize = 8;

                var colors = new[] { Color.Red, Color.Green, Color.Blue, Color.Yellow, Color.Pink, Color.MediumVioletRed };

                var prevPositionG = Vector3.PositiveInfinity;
                for (int i = 0; i < 4; i++)
                {
                    float levelCellSize = cellSize * (float)Math.Pow(2, i);
                    var   position      = MyEnvironment.CameraPosition;
                    //var position = Vector3.Zero;
                    position.Y = 0;
                    var positionG = position.Snap(levelCellSize * 2);

                    float radiusMin = radius[i];
                    float radiusMax = radius[i + 1];

                    // naive

                    var pmin = (positionG - radiusMax - levelCellSize * 2).Snap(levelCellSize * 2);
                    var pmax = (positionG + radiusMax + levelCellSize * 2).Snap(levelCellSize * 2);

                    //if(i==0)
                    //{
                    //    for (var x = pmin.X; x < pmax.X; x += levelCellSize)
                    //    {
                    //        for (var y = pmin.Y; y < pmax.Y; y += levelCellSize)
                    //        {
                    //            for (var z = pmin.Z; z < pmax.Z; z += levelCellSize)
                    //            {
                    //                var cell = new Vector3(x, y, z);
                    //                var rep = cell.Snap(levelCellSize * 2);

                    //                var inLevelGrid = (rep - positionG).Length() < radiusMax;
                    //                if(inLevelGrid)
                    //                {
                    //                    batch.AddBoundingBox(new BoundingBox(cell, cell + levelCellSize), colors[i]);
                    //                }
                    //            }
                    //        }
                    //    }
                    //}
                    //else
                    {
                        for (var x = pmin.X; x < pmax.X; x += levelCellSize)
                        {
                            for (var z = pmin.Z; z < pmax.Z; z += levelCellSize)
                            {
                                var cell = new Vector3(x, positionG.Y, z);
                                var rep  = cell.Snap(levelCellSize * 2);

                                var inPrevLevelGrid = (cell - prevPositionG).Length() < radiusMin;
                                var inLevelGrid     = (rep - positionG).Length() < radiusMax;

                                if (inLevelGrid && !inPrevLevelGrid)
                                {
                                    batch.AddBoundingBox(new BoundingBox(cell, cell + levelCellSize), colors[i]);
                                }
                            }
                        }
                    }

                    prevPositionG = positionG;
                }


                batch.Commit();
            }
        }
示例#24
0
        internal void Add(MyActor child)
        {
            child.AddComponent(MyComponentFactory <MyGroupLeafComponent> .Create());

            child.GetGroupLeaf().m_parent = m_owner;

            m_children.Add(child);

            if (child.m_relativeTransform == null)
            {
                child.m_relativeTransform = (Matrix)(child.WorldMatrix * MatrixD.Invert(m_owner.WorldMatrix));
            }

            if (!m_owner.m_localAabb.HasValue)
            {
                m_owner.m_localAabb = child.m_localAabb;
            }
            else
            {
                var localAabb = child.m_localAabb.Value;
                m_owner.m_localAabb = m_owner.m_localAabb.Value.Include(ref localAabb);
            }

            PropagateMatrixChange(child);

            if (child.GetRenderable() == null)
            {
                return;
            }

            //var mesh = child.GetRenderable().GetMesh();
            var model    = child.GetRenderable().GetModel();
            var material = MyMeshes.GetMeshPart(model, 0, 0).Info.Material;

            bool fracture = model.Info.RuntimeGenerated || model.Info.Dynamic;

            if (MyMeshMaterials1.IsMergable(material) && MyBigMeshTable.Table.IsMergable(model) && !fracture)
            {
                child.GetGroupLeaf().m_mergable = true;

                MyBigMeshTable.Table.AddMesh(model);
                m_mergablesCounter++;

                if (!m_isMerged && m_mergablesCounter >= MERGE_THRESHOLD)
                {
                    TurnIntoMergeInstancing();
                }
                else if (m_isMerged)
                {
                    Merge(child);
                }

                //var materialRk = MyMeshMaterials1.Table[material.Index].RepresentationKey;
                //var mergeGroupForMaterial = m_materialGroups.Get(materialRk);
                //if (mergeGroupForMaterial == null)
                //{
                //    var proxyIndex = m_materialGroups.Count;
                //    mergeGroupForMaterial = new MyMaterialMergeGroup(MyBigMeshTable.Table, material, proxyIndex);
                //    m_materialGroups[MyMeshMaterials1.Table[material.Index].RepresentationKey] = mergeGroupForMaterial;

                //    m_dirtyProxy = true;
                //}

                //child.GetRenderable().SetStandaloneRendering(false);
                //child.GetGroupLeaf().m_mergeGroup = mergeGroupForMaterial;


                //mergeGroupForMaterial.AddEntity(child, model);
                //mergeGroupForMaterial.UpdateEntity(child);
            }
            else
            {
                //Debug.WriteLine(String.Format("Mesh {0}, material {1} is not mergable", mesh.Name, material));
            }

            m_dirtyTree = true;
        }
        private static void UpdateSceneFrame()
        {
            var desc = new RasterizerStateDescription();

            desc.FillMode = FillMode.Solid;
            desc.CullMode = CullMode.None;
            desc.IsFrontCounterClockwise = true;

            desc.DepthBias            = 25000;
            desc.DepthBiasClamp       = 2;
            desc.SlopeScaledDepthBias = 1;

            MyPipelineStates.Modify(m_shadowRasterizerState, desc);


            MyMeshes.Load();
            QueryTexturesFromEntities();
            MyTextures.Load();
            GatherTextures();
            MyComponents.UpdateCullProxies();
            MyComponents.ProcessEntities();
            MyComponents.SendVisible();

            MyBillboardRenderer.OnFrameStart();

            MyRender11.GetRenderProfiler().StartProfilingBlock("RebuildProxies");
            foreach (var renderable in MyComponentFactory <MyRenderableComponent> .GetAll())
            {
                renderable.RebuildRenderProxies();
            }
            MyRender11.GetRenderProfiler().EndProfilingBlock();

            MyRender11.GetRenderProfiler().StartProfilingBlock("UpdateProxies");
            UpdateActors();
            MyRender11.GetRenderProfiler().EndProfilingBlock();

            MyBigMeshTable.Table.MoveToGPU();

            MyRender11.GetRenderProfiler().StartProfilingBlock("Update merged groups");
            MyRender11.GetRenderProfiler().StartProfilingBlock("UpdateBeforeDraw");
            foreach (var r in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                r.UpdateBeforeDraw();
            }
            MyRender11.GetRenderProfiler().EndProfilingBlock();

            MyRender11.GetRenderProfiler().StartProfilingBlock("MoveToGPU");
            foreach (var r in MyComponentFactory <MyGroupRootComponent> .GetAll())
            {
                foreach (var val in r.m_materialGroups.Values)
                {
                    // optimize: keep list+set for updating
                    val.MoveToGPU();
                }
            }
            MyRender11.GetRenderProfiler().EndProfilingBlock();
            MyRender11.GetRenderProfiler().EndProfilingBlock();

            MyRender11.GetRenderProfiler().StartProfilingBlock("Fill foliage streams");
            MyGpuProfiler.IC_BeginBlock("Fill foliage streams");
            MyGPUFoliageGenerating.GetInstance().PerFrame();
            MyGPUFoliageGenerating.GetInstance().Begin();
            foreach (var foliage in MyComponentFactory <MyFoliageComponent> .GetAll())
            {
                if (foliage.m_owner.CalculateCameraDistance() < MyRender11.RenderSettings.FoliageDetails.GrassDrawDistance())
                {
                    foliage.FillStreams();
                }
                else
                {
                    foliage.InvalidateStreams();
                }
            }
            MyGPUFoliageGenerating.GetInstance().End();
            MyGpuProfiler.IC_EndBlock();
            MyRender11.GetRenderProfiler().EndProfilingBlock();

            MyCommon.MoveToNextFrame();
        }
        private static void ProcessMessageInternal(IMyRenderMessage message)
        {
            switch (message.MessageType)
            {
            case MyRenderMessageEnum.SetCameraViewMatrix:
            {
                var rMessage = (MyRenderMessageSetCameraViewMatrix)message;

                SetupCameraMatrices(rMessage);

                break;
            }

            case MyRenderMessageEnum.DrawScene:
            {
                var rMessage = (IMyRenderMessage)message;

                m_drawQueue.Enqueue(rMessage);

                m_messageTracker.Clear();

                break;
            }

            case MyRenderMessageEnum.RebuildCullingStructure:
            {
                break;
            }

                #region Profiler

            case MyRenderMessageEnum.RenderProfiler:
            {
                var profMessage = (MyRenderMessageRenderProfiler)message;

                MyRenderProfiler.HandleInput(profMessage.Command, profMessage.Index);

                break;
            }

                #endregion

                #region Characters

            case MyRenderMessageEnum.CreateRenderCharacter:
            {
                var rMessage = (MyRenderMessageCreateRenderCharacter)message;

                var    actor        = MyActorFactory.CreateCharacter();
                Matrix worldMatrixF = rMessage.WorldMatrix;
                //actor.GetRenderable().SetModel(MyAssetsLoader.GetModel(rMessage.Model));
                actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(rMessage.Model)));
                actor.SetMatrix(ref worldMatrixF);

                if (rMessage.ColorMaskHSV.HasValue)
                {
                    var color = ColorFromMask(rMessage.ColorMaskHSV.Value);
                    actor.GetRenderable().SetKeyColor(new Vector4(color, 1));
                }

                actor.SetID(rMessage.ID);

                //var entity = MyComponents.CreateEntity(rMessage.ID);
                //MyComponents.CreateRenderable(
                //    entity,
                //    MyMeshes.GetMeshId(X.TEXT(rMessage.Model)),
                //    rMessage.ColorMaskHSV.HasValue ? rMessage.ColorMaskHSV.Value : Vector3.One);
                //MyComponents.SetMatrix(entity, ref rMessage.WorldMatrix);

                break;
            }

            case MyRenderMessageEnum.SetCharacterSkeleton:
            {
                var rMessage = (MyRenderMessageSetCharacterSkeleton)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.CharacterID);

                if (actor != null)
                {
                    actor.GetSkinning().SetSkeleton(rMessage.SkeletonBones, rMessage.SkeletonIndices);
                }

                //var entity = MyComponents.GetEntity(rMessage.CharacterID);
                //MyComponents.SetSkeleton(entity, rMessage.SkeletonBones, rMessage.SkeletonIndices);

                break;
            };

            case MyRenderMessageEnum.SetCharacterTransforms:
            {
                var rMessage = (MyRenderMessageSetCharacterTransforms)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.CharacterID);

                if (actor != null)
                {
                    actor.GetSkinning().SetAnimationBones(rMessage.RelativeBoneTransforms);
                }
                //var entity = MyComponents.GetEntity(rMessage.CharacterID);
                //MyComponents.SetAnimation(entity, rMessage.RelativeBoneTransforms);

                break;
            }

            case MyRenderMessageEnum.UpdateRenderEntity:
            {
                var rMessage = (MyRenderMessageUpdateRenderEntity)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                if (actor != null && actor.GetRenderable() != null)
                {
                    if (rMessage.ColorMaskHSV.HasValue)
                    {
                        actor.GetRenderable().SetKeyColor(new Vector4(ColorFromMask(rMessage.ColorMaskHSV.Value), 1));
                    }
                    actor.GetRenderable().SetDithering(rMessage.Dithering);

                    if (rMessage.Dithering < 0)
                    {
                    }
                }

                break;
            }

            case MyRenderMessageEnum.ChangeModelMaterial:
            {
                var rMessage = (MyRenderMessageChangeModelMaterial)message;



                //var matId = MyMeshMaterialId.NULL;
                //if (rMessage.Material.ToLower().Contains("debug"))
                //{
                //    matId = MyMeshMaterials1.DebugMaterialId;
                //}
                //else
                //{
                //    matId = MyMeshMaterials1.GetMaterialId(rMessage.Material);
                //}

                //MyAssetsLoader.GetModel(rMessage.Model).SetMaterial_SLOW(MyMeshMaterials1.GetProxyId(matId));

                break;
            }

                #endregion

                #region Render objects

            case MyRenderMessageEnum.CreateRenderEntity:
            {
                var rMessage = (MyRenderMessageCreateRenderEntity)message;

                Matrix m = (Matrix)rMessage.WorldMatrix;

                var actor = MyActorFactory.CreateSceneObject();
                if (rMessage.Model != null)
                {
                    var model = MyAssetsLoader.ModelRemap.Get(rMessage.Model, rMessage.Model);

                    actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(model)));
                    //if (MyDestructionMesh.ModelsDictionary.ContainsKey(model))
                    //{
                    //    //actor.GetRenderable().SetModel(MyDestructionMesh.ModelsDictionary.Get(model));
                    //    actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(model)));
                    //}
                    //else
                    //{
                    //    //actor.GetRenderable().SetModel(MyAssetsLoader.GetModel(model));
                    //    actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(model)));
                    //}
                }

                actor.SetID(rMessage.ID);
                actor.SetMatrix(ref m);

                break;
            }

            case MyRenderMessageEnum.CreateRenderVoxelDebris:
            {
                var rMessage = (MyRenderMessageCreateRenderVoxelDebris)message;

                Matrix m = (Matrix)rMessage.WorldMatrix;

                var actor = MyActorFactory.CreateSceneObject();
                if (rMessage.Model != null)
                {
                    actor.GetRenderable().SetModel(MyMeshes.GetMeshId(X.TEXT(rMessage.Model)));
                }

                actor.SetID(rMessage.ID);
                actor.SetMatrix(ref m);

                MyRenderableComponent.DebrisEntityVoxelMaterial[rMessage.ID] = rMessage.VoxelMaterialIndex;

                break;
            }

            case MyRenderMessageEnum.UpdateRenderObject:
            {
                var rMessage = (MyRenderMessageUpdateRenderObject)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                if (actor != null)
                {
                    Matrix m = (Matrix)rMessage.WorldMatrix;
                    actor.SetMatrix(ref m);
                    if (rMessage.AABB.HasValue)
                    {
                        actor.SetAabb((BoundingBox)rMessage.AABB.Value);
                    }
                }

                var entity = MyComponents.GetEntity(rMessage.ID);
                if (entity != EntityId.NULL)
                {
                    MyComponents.SetMatrix(entity, ref rMessage.WorldMatrix);
                    if (rMessage.AABB.HasValue)
                    {
                        var aabb = rMessage.AABB.Value;
                        MyComponents.SetAabb(entity, ref aabb);
                    }
                }

                break;
            }

            case MyRenderMessageEnum.RemoveRenderObject:
            {
                var rMessage = (MyRenderMessageRemoveRenderObject)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                if (actor != null)
                {
                    if (actor.GetRenderable() != null && actor.GetRenderable().GetModel().Info.Dynamic)
                    {
                        MyMeshes.RemoveMesh(actor.GetRenderable().GetModel());
                    }

                    actor.Destruct();
                }

                var instancing = MyInstancing.Get(rMessage.ID);
                if (instancing != InstancingId.NULL)
                {
                    MyInstancing.Remove(rMessage.ID, instancing);
                }

                var light = MyLights.Get(rMessage.ID);
                if (light != LightId.NULL)
                {
                    MyLights.Remove(rMessage.ID, light);
                }

                var clipmap = MyClipmapFactory.ClipmapByID.Get(rMessage.ID);
                if (clipmap != null)
                {
                    clipmap.RemoveFromUpdate();
                }

                break;
            }

            case MyRenderMessageEnum.UpdateRenderObjectVisibility:
            {
                var rMessage = (MyRenderMessageUpdateRenderObjectVisibility)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                if (actor != null)
                {
                    actor.SetVisibility(rMessage.Visible);
                }

                break;
            }


            case MyRenderMessageEnum.CreateRenderInstanceBuffer:
            {
                var rMessage = (MyRenderMessageCreateRenderInstanceBuffer)message;

                //var instancing = MyComponentFactory<MyInstancingComponent>.Create();
                //instancing.SetID(rMessage.ID);
                //instancing.Init(rMessage.Type);
                //instancing.SetDebugName(rMessage.DebugName);

                MyInstancing.Create(rMessage.ID, rMessage.Type, rMessage.DebugName);

                break;
            }

            case MyRenderMessageEnum.UpdateRenderInstanceBuffer:
            {
                var rMessage = (MyRenderMessageUpdateRenderInstanceBuffer)message;

                //var instancing = MyIDTracker<MyInstancingComponent>.FindByID(rMessage.ID);
                //if(instancing != null)
                //{
                //    instancing.UpdateGeneric(rMessage.InstanceData, rMessage.Capacity);
                //}

                MyInstancing.UpdateGeneric(MyInstancing.Get(rMessage.ID), rMessage.InstanceData, rMessage.Capacity);

                rMessage.InstanceData.Clear();

                break;
            }

            case MyRenderMessageEnum.UpdateRenderCubeInstanceBuffer:
            {
                var rMessage = (MyRenderMessageUpdateRenderCubeInstanceBuffer)message;

                //var instancing = MyIDTracker<MyInstancingComponent>.FindByID(rMessage.ID);
                //if (instancing != null)
                //{
                //    instancing.UpdateCube(rMessage.InstanceData, rMessage.Capacity);
                //}
                MyInstancing.UpdateCube(MyInstancing.Get(rMessage.ID), rMessage.InstanceData, rMessage.Capacity);

                rMessage.InstanceData.Clear();

                break;
            }

            case MyRenderMessageEnum.SetInstanceBuffer:
            {
                var rMessage = (MyRenderMessageSetInstanceBuffer)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                //var instancing = MyIDTracker<MyInstancingComponent>.FindByID(rMessage.InstanceBufferId);

                if (actor != null)
                {
                    //if (actor.GetComponent(MyActorComponentEnum.Instancing) != instancing)
                    //{
                    //    actor.AddComponent(instancing);
                    //}
                    //actor.SetLocalAabb(rMessage.LocalAabb);
                    //actor.GetRenderable().SetInstancingCounters(rMessage.InstanceCount, rMessage.InstanceStart);

                    actor.GetRenderable().SetInstancing(MyInstancing.Get(rMessage.InstanceBufferId));
                    actor.SetLocalAabb(rMessage.LocalAabb);
                    actor.GetRenderable().SetInstancingCounters(rMessage.InstanceCount, rMessage.InstanceStart);
                }

                break;
            }

            case MyRenderMessageEnum.CreateManualCullObject:
            {
                var rMessage = (MyRenderMessageCreateManualCullObject)message;

                var actor = MyActorFactory.CreateGroup();
                actor.SetID(rMessage.ID);
                Matrix m = (Matrix)rMessage.WorldMatrix;
                actor.SetMatrix(ref m);

                break;
            }

            case MyRenderMessageEnum.SetParentCullObject:
            {
                var rMessage = (MyRenderMessageSetParentCullObject)message;

                var child = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                var parent = MyIDTracker <MyActor> .FindByID(rMessage.CullObjectID);

                if (child != null && parent != null && parent.GetGroupRoot() != null && child.GetGroupLeaf() == null)
                {
                    child.SetRelativeTransform(rMessage.ChildToParent);
                    parent.GetGroupRoot().Add(child);
                }

                break;
            }

            case MyRenderMessageEnum.CreateLineBasedObject:
            {
                var rMessage = (MyRenderMessageCreateLineBasedObject)message;

                var actor = MyActorFactory.CreateSceneObject();
                //actor.GetRenderable().SetModel(new MyDynamicMesh());

                actor.SetID(rMessage.ID);
                actor.SetMatrix(ref Matrix.Identity);

                MyMeshMaterials1.GetMaterialId("__ROPE_MATERIAL", null, "Textures/rope_cm.dds", "Textures/rope_ng.dds", "Textures/rope_add.dds", MyMesh.DEFAULT_MESH_TECHNIQUE);
                actor.GetRenderable().SetModel(MyMeshes.CreateRuntimeMesh(X.TEXT("LINE" + rMessage.ID), 1, true));

                break;
            }

            case MyRenderMessageEnum.UpdateLineBasedObject:
            {
                var rMessage = (MyRenderMessageUpdateLineBasedObject)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                if (actor != null)
                {
                    //var mesh = actor.GetRenderable().GetMesh() as MyDynamicMesh;

                    MyVertexFormatPositionH4 []            stream0;
                    MyVertexFormatTexcoordNormalTangent [] stream1;

                    MyLineHelpers.GenerateVertexData(ref rMessage.WorldPointA, ref rMessage.WorldPointB,
                                                     out stream0, out stream1);

                    var indices  = MyLineHelpers.GenerateIndices(stream0.Length);
                    var sections = new MySectionInfo[]
                    {
                        new MySectionInfo {
                            TriCount = indices.Length / 3, IndexStart = 0, MaterialName = "__ROPE_MATERIAL"
                        }
                    };

                    MyMeshes.UpdateRuntimeMesh(MyMeshes.GetMeshId(X.TEXT("LINE" + rMessage.ID)),
                                               indices,
                                               stream0,
                                               stream1,
                                               sections,
                                               (BoundingBox)MyLineHelpers.GetBoundingBox(ref rMessage.WorldPointA, ref rMessage.WorldPointB));

                    //actor.SetAabb((BoundingBox)MyLineHelpers.GetBoundingBox(ref rMessage.WorldPointA, ref rMessage.WorldPointB));
                    actor.MarkRenderDirty();

                    var matrix = Matrix.CreateTranslation((Vector3)(rMessage.WorldPointA + rMessage.WorldPointB) * 0.5f);
                    actor.SetMatrix(ref matrix);
                }

                break;
            }

            case MyRenderMessageEnum.SetRenderEntityData:
            {
                var rMessage = (MyRenderMessageSetRenderEntityData)message;

                Debug.Assert(false, "MyRenderMessageSetRenderEntityData is deprecated!");

                break;
            }

            case MyRenderMessageEnum.AddRuntimeModel:
            {
                var rMessage = (MyRenderMessageAddRuntimeModel)message;

                //MyDestructionMesh mesh = MyDestructionMesh.ModelsDictionary.Get(rMessage.Name);
                //if (mesh == null)
                //{
                //mesh = new MyDestructionMesh(rMessage.Name);

                //ProfilerShort.Begin("LoadBuffers");
                //mesh.Fill(rMessage.ModelData.Indices, rMessage.ModelData.Positions, rMessage.ModelData.Normals, rMessage.ModelData.Tangents, rMessage.ModelData.TexCoords, rMessage.ModelData.Sections, rMessage.ModelData.AABB);
                //ProfilerShort.End();

                if (!MyMeshes.Exists(rMessage.Name))
                {
                    {
                        ushort[] indices = new ushort[rMessage.ModelData.Indices.Count];
                        for (int i = 0; i < rMessage.ModelData.Indices.Count; i++)
                        {
                            indices[i] = (ushort)rMessage.ModelData.Indices[i];
                        }
                        var verticesNum = rMessage.ModelData.Positions.Count;
                        MyVertexFormatPositionH4[]            stream0 = new MyVertexFormatPositionH4[verticesNum];
                        MyVertexFormatTexcoordNormalTangent[] stream1 = new MyVertexFormatTexcoordNormalTangent[verticesNum];
                        for (int i = 0; i < verticesNum; i++)
                        {
                            stream0[i] = new MyVertexFormatPositionH4(rMessage.ModelData.Positions[i]);
                            stream1[i] = new MyVertexFormatTexcoordNormalTangent(
                                rMessage.ModelData.TexCoords[i], rMessage.ModelData.Normals[i], rMessage.ModelData.Tangents[i]);
                        }
                        var id = MyMeshes.CreateRuntimeMesh(X.TEXT(rMessage.Name), rMessage.ModelData.Sections.Count, false);
                        MyMeshes.UpdateRuntimeMesh(id, indices, stream0, stream1, rMessage.ModelData.Sections.ToArray(), rMessage.ModelData.AABB);
                    }

                    if (rMessage.ReplacedModel != null)
                    {
                        //MyAssetsLoader.ModelRemap[rMessage.ReplacedModel] = rMessage.Name;
                        MyAssetsLoader.ModelRemap[rMessage.Name] = rMessage.ReplacedModel;
                    }

                    //if (MyAssetsLoader.LOG_MESH_STATISTICS)
                    //{
                    //    mesh.DebugWriteInfo();
                    //}
                }

                break;
            }

            case MyRenderMessageEnum.UpdateModelProperties:
            {
                var rMessage = (MyRenderMessageUpdateModelProperties)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID);

                if (actor != null)
                {
                    var key = new MyEntityMaterialKey {
                        LOD = rMessage.LOD, Material = X.TEXT(rMessage.MaterialName)
                    };

                    if (rMessage.Enabled.HasValue)
                    {
                        if (!MyScene.EntityDisabledMaterials.ContainsKey(rMessage.ID))
                        {
                            MyScene.EntityDisabledMaterials.Add(rMessage.ID, new HashSet <MyEntityMaterialKey>());
                        }

                        if (!rMessage.Enabled.Value)
                        {
                            MyScene.EntityDisabledMaterials[rMessage.ID].Add(key);
                        }
                        else
                        {
                            MyScene.EntityDisabledMaterials[rMessage.ID].Remove(key);
                        }
                    }

                    var r = actor.GetRenderable();

                    if ((rMessage.Emissivity.HasValue || rMessage.DiffuseColor.HasValue) && !r.ModelProperties.ContainsKey(key))
                    {
                        r.ModelProperties[key] = new MyModelProperties();
                    }

                    if (rMessage.Emissivity.HasValue)
                    {
                        r.ModelProperties[key].Emissivity = rMessage.Emissivity.Value;
                    }

                    if (rMessage.DiffuseColor.HasValue)
                    {
                        r.ModelProperties[key].ColorMul = rMessage.DiffuseColor.Value;
                    }

                    actor.MarkRenderDirty();
                }

                break;
            }

            case MyRenderMessageEnum.PreloadModel:
            {
                var rMessage = (MyRenderMessagePreloadModel)message;

                //MyAssetsLoader.GetModel(rMessage.Name);
                MyMeshes.GetMeshId(X.TEXT(rMessage.Name));

                break;
            }

            case MyRenderMessageEnum.ChangeMaterialTexture:
            {
                var rMessage = (MyRenderMessageChangeMaterialTexture)message;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.RenderObjectID);

                if (actor != null)
                {
                    var r   = actor.GetRenderable();
                    var key = new MyEntityMaterialKey {
                        LOD = 0, Material = X.TEXT(rMessage.MaterialName)
                    };

                    if (!r.ModelProperties.ContainsKey(key))
                    {
                        r.ModelProperties[key] = new MyModelProperties();
                    }
                    r.ModelProperties[key].TextureSwap = new MyMaterialTextureSwap {
                        TextureName = X.TEXT(rMessage.TextureName)
                    };

                    r.FreeCustomRenderTextures(key);

                    actor.MarkRenderDirty();
                }

                break;
            }

            case MyRenderMessageEnum.DrawTextToMaterial:
            {
                var rMessage = (MyRenderMessageDrawTextToMaterial)message;

                //rMessage.EntityId
                //rMessage.FontColor
                //rMessage.MaterialName
                //rMessage.Text;
                //rMessage.TextScale;

                var actor = MyIDTracker <MyActor> .FindByID(rMessage.RenderObjectID);

                if (actor != null)
                {
                    var r   = actor.GetRenderable();
                    var key = new MyEntityMaterialKey {
                        LOD = 0, Material = X.TEXT(rMessage.MaterialName)
                    };

                    if (!r.ModelProperties.ContainsKey(key))
                    {
                        r.ModelProperties[key] = new MyModelProperties();
                    }
                    else
                    {
                        r.ModelProperties[key].TextureSwap = null;
                    }

                    RwTexId handle = r.ModelProperties[key].CustomRenderedTexture;
                    if (handle == RwTexId.NULL && MyModelProperties.CustomTextures < MyModelProperties.MaxCustomTextures)
                    {
                        handle = MyRwTextures.CreateRenderTarget(rMessage.TextureResolution * rMessage.TextureAspectRatio, rMessage.TextureResolution, SharpDX.DXGI.Format.R8G8B8A8_UNorm_SRgb, true);
                        r.ModelProperties[key].CustomRenderedTexture = handle;
                        ++MyModelProperties.CustomTextures;
                    }

                    if (handle != RwTexId.NULL)
                    {
                        var clearColor = new SharpDX.Color4(rMessage.BackgroundColor.PackedValue);
                        clearColor.Alpha = 0;
                        MyRender11.ImmediateContext.ClearRenderTargetView(handle.Rtv, clearColor);

                        // my sprites renderer -> push state
                        MySpritesRenderer.PushState(new Vector2(rMessage.TextureResolution * rMessage.TextureAspectRatio, rMessage.TextureResolution));


                        MySpritesRenderer.DrawText(Vector2.Zero, new StringBuilder(rMessage.Text), rMessage.FontColor, rMessage.TextScale);
                        // render text with fonts to rt
                        // update texture of proxy
                        MySpritesRenderer.Draw(handle.Rtv, new MyViewport(rMessage.TextureResolution * rMessage.TextureAspectRatio, rMessage.TextureResolution));

                        // render to rt
                        // my sprites renderer -> pop state
                        MySpritesRenderer.PopState();


                        MyRender11.ImmediateContext.GenerateMips(handle.ShaderView);

                        actor.MarkRenderDirty();
                    }
                    else
                    {
                        MyRenderProxy.TextNotDrawnToTexture(rMessage.EntityId);
                    }
                }
                else
                {
                    MyRenderProxy.TextNotDrawnToTexture(rMessage.EntityId);
                }

                break;
            }

            case MyRenderMessageEnum.PreloadMaterials:
            {
                var rMessage = (MyRenderMessagePreloadMaterials)message;

                //MyAssetsLoader.GetMaterials(rMessage.Name);
                MyMeshes.GetMeshId(X.TEXT(rMessage.Name));

                break;
            }

                #endregion

                #region Voxels

            case MyRenderMessageEnum.CreateClipmap:
            {
                var rMessage = (MyRenderMessageCreateClipmap)message;

                var clipmap = new MyClipmapHandler(rMessage.ClipmapId, rMessage.ScaleGroup, rMessage.WorldMatrix, rMessage.SizeLod0);
                MyClipmapFactory.ClipmapByID[rMessage.ClipmapId] = clipmap;
                clipmap.Base.LoadContent();


                break;
            }

            case MyRenderMessageEnum.UpdateClipmapCell:
            {
                var rMessage = (MyRenderMessageUpdateClipmapCell)message;

                var clipmap = MyClipmapFactory.ClipmapByID.Get(rMessage.ClipmapId);
                if (clipmap != null)
                {
                    clipmap.Base.UpdateCell(rMessage);
                }

                rMessage.Batches.Clear();
                break;
            }

            case MyRenderMessageEnum.InvalidateClipmapRange:
            {
                var rMessage = (MyRenderMessageInvalidateClipmapRange)message;

                var clipmap = MyClipmapFactory.ClipmapByID.Get(rMessage.ClipmapId);
                if (clipmap != null)
                {
                    clipmap.Base.InvalidateRange(rMessage.MinCellLod0, rMessage.MaxCellLod0);
                }

                break;
            }

            case MyRenderMessageEnum.CreateRenderVoxelMaterials:
            {
                var rMessage = (MyRenderMessageCreateRenderVoxelMaterials)message;

                Debug.Assert(MyVoxelMaterials1.CheckIndices(rMessage.Materials));
                MyVoxelMaterials1.Set(rMessage.Materials);

                rMessage.Materials = null;

                break;
            }


                #endregion

                #region Lights

            case MyRenderMessageEnum.CreateRenderLight:
            {
                var rMessage = (MyRenderMessageCreateRenderLight)message;

                //MyLight.Create(rMessage.ID);

                MyLights.Create(rMessage.ID);

                break;
            }

            case MyRenderMessageEnum.UpdateRenderLight:
            {
                var rMessage = (MyRenderMessageUpdateRenderLight)message;


                var light = MyLights.Get(rMessage.ID);

                if (light != LightId.NULL)
                {
                    var lightInfo = new MyLightInfo
                    {
                        Position           = rMessage.Position,
                        PositionWithOffset = rMessage.Position + rMessage.Offset * rMessage.Range * rMessage.ReflectorDirection,
                        CastsShadows       = rMessage.CastShadows,
                        ShadowsDistance    = rMessage.ShadowDistance,
                        ParentGID          = rMessage.ParentID,
                        UsedInForward      = rMessage.UseInForwardRender
                    };

                    MyLights.UpdateEntity(light, ref lightInfo);

                    if ((rMessage.Type & LightTypeEnum.PointLight) > 0)
                    {
                        MyLights.UpdatePointlight(light, rMessage.LightOn, rMessage.Range, new Vector3(rMessage.Color.R, rMessage.Color.G, rMessage.Color.B) / 255.0f * rMessage.Intensity, rMessage.Falloff);
                    }
                    if ((rMessage.Type & LightTypeEnum.Hemisphere) > 0)
                    {
                        //rMessage.Color;
                        //rMessage.Falloff;
                        //rMessage.Intensity;
                        //rMessage.LightOn;
                        //rMessage.ReflectorDirection;
                        //rMessage.ReflectorUp;
                    }
                    if ((rMessage.Type & LightTypeEnum.Spotlight) > 0)
                    {
                        // because it's so in dx9...
                        float coneMaxAngleCos = 1 - rMessage.ReflectorConeMaxAngleCos;
                        coneMaxAngleCos = (float)Math.Min(Math.Max(coneMaxAngleCos, 0.01), 0.99f);
                        MyLights.UpdateSpotlight(light, rMessage.ReflectorOn,
                                                 rMessage.ReflectorDirection, rMessage.ReflectorRange, coneMaxAngleCos, rMessage.ReflectorUp,
                                                 new Vector3(rMessage.ReflectorColor.R, rMessage.ReflectorColor.G, rMessage.ReflectorColor.B) / 255.0f * rMessage.Intensity, rMessage.ReflectorFalloff,
                                                 MyTextures.GetTexture(rMessage.ReflectorTexture, MyTextureEnum.CUSTOM));
                    }

                    if (rMessage.GlareOn)
                    {
                        MyLights.UpdateGlare(light, new MyGlareDesc
                            {
                                Enabled     = rMessage.GlareOn,
                                Material    = X.TEXT(rMessage.GlareMaterial),
                                Intensity   = rMessage.GlareIntensity,
                                QuerySize   = rMessage.GlareQuerySize,
                                Type        = rMessage.GlareType,
                                Size        = rMessage.GlareSize,
                                MaxDistance = rMessage.GlareMaxDistance,
                                Color       = rMessage.Color,
                                Direction   = rMessage.ReflectorDirection,
                                Range       = rMessage.Range
                            });
                    }
                }

                break;
            }

            case MyRenderMessageEnum.SetLightShadowIgnore:
            {
                var rMessage = (MyRenderMessageSetLightShadowIgnore)message;

                var light = MyLights.Get(rMessage.ID);
                var actor = MyIDTracker <MyActor> .FindByID(rMessage.ID2);

                if (light != LightId.NULL && actor != null)
                {
                    if (!MyLights.IgnoredEntitites.ContainsKey(light))
                    {
                        MyLights.IgnoredEntitites[light] = new HashSet <uint>();
                    }
                    MyLights.IgnoredEntitites[light].Add(rMessage.ID2);
                }

                break;
            }


            case MyRenderMessageEnum.ClearLightShadowIgnore:
            {
                var rMessage = (MyRenderMessageClearLightShadowIgnore)message;

                var light = MyLights.Get(rMessage.ID);
                if (light != LightId.NULL)
                {
                    MyLights.IgnoredEntitites.Remove(light);
                }

                break;
            }

            case MyRenderMessageEnum.UpdateFogSettings:
            {
                var rMessage = (MyRenderMessageUpdateFogSettings)message;

                MyEnvironment.FogSettings = rMessage.Settings;

                break;
            }

            case MyRenderMessageEnum.UpdateRenderEnvironment:
            {
                var rMessage = (MyRenderMessageUpdateRenderEnvironment)message;

                MyEnvironment.DirectionalLightDir       = VRageMath.Vector3.Normalize(rMessage.SunDirection);
                MyEnvironment.DirectionalLightIntensity = rMessage.SunIntensity * rMessage.SunColor.ToVector3();
                MyEnvironment.DirectionalLightEnabled   = rMessage.SunLightOn;
                MyEnvironment.DayTime           = (float)(rMessage.DayTime - Math.Truncate(rMessage.DayTime));
                MyEnvironment.SunDistance       = rMessage.DistanceToSun;
                MyEnvironment.SunColor          = rMessage.SunColor;
                MyEnvironment.SunMaterial       = rMessage.SunMaterial;
                MyEnvironment.SunSizeMultiplier = rMessage.SunSizeMultiplier;

                var skybox = rMessage.BackgroundTexture;

                m_resetEyeAdaptation = m_resetEyeAdaptation || rMessage.ResetEyeAdaptation;

                break;
            }

            case MyRenderMessageEnum.UpdateEnvironmentMap:
            {
                break;
            }

            case MyRenderMessageEnum.UpdatePostprocessSettings:
            {
                var rMessage = (MyRenderMessageUpdatePostprocessSettings)message;

                m_postprocessSettings = rMessage.Settings;

                break;
            }

            case MyRenderMessageEnum.UpdateSSAOSettings:
            {
                var rMessage = (MyRenderMessageUpdateSSAOSettings)message;


                MySSAO.Params.MinRadius  = rMessage.MinRadius;
                MySSAO.Params.MaxRadius  = rMessage.MaxRadius;
                MySSAO.Params.RadiusGrow = rMessage.RadiusGrowZScale;

                MySSAO.Params.RadiusBias    = rMessage.Bias;
                MySSAO.Params.Falloff       = rMessage.Falloff;
                MySSAO.Params.Normalization = rMessage.NormValue;
                MySSAO.Params.Contrast      = rMessage.Contrast;

                break;
            }

                #endregion

                #region Sprites
            case MyRenderMessageEnum.DrawSprite:
            case MyRenderMessageEnum.DrawSpriteNormalized:
            case MyRenderMessageEnum.DrawSpriteAtlas:
            case MyRenderMessageEnum.SpriteScissorPush:
            case MyRenderMessageEnum.SpriteScissorPop:
            {
                m_drawQueue.Enqueue(message);
                break;
            }

                #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:
            {
                m_drawQueue.Enqueue(message);
                break;
            }

                #endregion

                #region Textures

            case MyRenderMessageEnum.PreloadTextures:
            {
                var preloadMsg = message as MyRenderMessagePreloadTextures;

                //MyTextureManager.PreloadTextures(preloadMsg.InDirectory, preloadMsg.Recursive);
                //MyTextures.UnloadTexture(texMessage.Texture);

                break;
            }

            case MyRenderMessageEnum.UnloadTexture:
            {
                var texMessage = (MyRenderMessageUnloadTexture)message;

                //MyTextureManager.UnloadTexture(texMessage.Texture);
                MyTextures.UnloadTexture(texMessage.Texture);

                break;
            }

            case MyRenderMessageEnum.ReloadTextures:
            {
                var reloadMsg = (MyRenderMessageReloadTextures)message;

                MyVoxelMaterials1.InvalidateMaterials();
                MyMeshMaterials1.InvalidateMaterials();
                MyTextures.ReloadAssetTextures();

                //MyTextureManager.UnloadTextures();
                //MyMaterialProxyFactory.ReloadTextures();

                break;
            }

            case MyRenderMessageEnum.ReloadModels:
            {
                var reloadMsg = (MyRenderMessageReloadModels)message;

                //MyMaterials.Clear();
                MyAssetsLoader.ReloadMeshes();
                MyRenderableComponent.MarkAllDirty();

                break;
            }

                #endregion

            case MyRenderMessageEnum.TakeScreenshot:
            {
                var rMessage = (MyRenderMessageTakeScreenshot)message;

                m_screenshot = new MyScreenshot(rMessage.PathToSave, rMessage.SizeMultiplier, rMessage.IgnoreSprites);

                break;
            }

            case MyRenderMessageEnum.ReloadEffects:
            {
                m_reloadShaders = true;

                //MyShaderBundleFactory.ClearCache();
                //MyShaderMaterial.ClearCache();
                //MyShaderPass.ClearCache();

                MyShaders.Recompile();
                MyMaterialShaders.Recompile();

                MyRenderableComponent.MarkAllDirty();

                foreach (var f in MyComponentFactory <MyFoliageComponent> .GetAll())
                {
                    f.Dispose();
                }

                break;
            }

            case MyRenderMessageEnum.PlayVideo:
            {
                var rMessage = (MyRenderMessagePlayVideo)message;

                MyVideoFactory.Create(rMessage.ID, rMessage.VideoFile);
                var video = MyVideoFactory.Videos.Get(rMessage.ID);
                if (video != null)
                {
                    video.Volume = rMessage.Volume;
                }

                break;
            }

            case MyRenderMessageEnum.CloseVideo:
            {
                var rMessage = (MyRenderMessageCloseVideo)message;

                var video = MyVideoFactory.Videos.Get(rMessage.ID);
                if (video != null)
                {
                    video.Stop();
                    video.Dispose();
                    MyVideoFactory.Videos.Remove(rMessage.ID);
                }

                break;
            }

            case MyRenderMessageEnum.DrawVideo:
            {
                var rMessage = (MyRenderMessageDrawVideo)message;

                var video = MyVideoFactory.Videos.Get(rMessage.ID);
                if (video != null)
                {
                    video.Draw(rMessage.Rectangle, rMessage.Color, rMessage.FitMode);
                }

                break;
            }

            case MyRenderMessageEnum.UpdateVideo:
            {
                var rMessage = (MyRenderMessageUpdateVideo)message;

                var video = MyVideoFactory.Videos.Get(rMessage.ID);
                if (video != null)
                {
                    video.Update();
                }

                break;
            }

            case MyRenderMessageEnum.SetVideoVolume:
            {
                var rMessage = (MyRenderMessageSetVideoVolume)message;

                var video = MyVideoFactory.Videos.Get(rMessage.ID);
                if (video != null)
                {
                    video.Volume = rMessage.Volume;
                }

                break;
            }

            case MyRenderMessageEnum.VideoAdaptersRequest:
            {
                MyRenderProxy.SendVideoAdapters(GetAdaptersList());
                break;
            }

            case MyRenderMessageEnum.SwitchDeviceSettings:
            {
                MyRenderProxy.RenderThread.SwitchSettings((message as MyRenderMessageSwitchDeviceSettings).Settings);
                break;
            }

            case MyRenderMessageEnum.SwitchRenderSettings:
                break;         // Can be ignored as we're handling newer version of the message.

            case MyRenderMessageEnum.SwitchRenderSettings1:
            {
                UpdateRenderSettings((message as MyRenderMessageSwitchRenderSettings1).Settings);
                break;
            }

            case MyRenderMessageEnum.UnloadData:
            {
                MyRender11.UnloadData();
                break;
            }

            case MyRenderMessageEnum.CollectGarbage:
            {
                GC.Collect();
                break;
            }

                #region Debug draw

            case MyRenderMessageEnum.DebugDrawPoint:
            case MyRenderMessageEnum.DebugDrawLine3D:
            case MyRenderMessageEnum.DebugDrawLine2D:
            case MyRenderMessageEnum.DebugDrawSphere:
            case MyRenderMessageEnum.DebugDrawAABB:
            case MyRenderMessageEnum.DebugDrawAxis:
            case MyRenderMessageEnum.DebugDrawOBB:
            case MyRenderMessageEnum.DebugDrawCone:
            case MyRenderMessageEnum.DebugDrawTriangle:
            case MyRenderMessageEnum.DebugDrawCapsule:
            case MyRenderMessageEnum.DebugDrawText2D:
            case MyRenderMessageEnum.DebugDrawText3D:
            case MyRenderMessageEnum.DebugDrawModel:
            case MyRenderMessageEnum.DebugDrawTriangles:
            case MyRenderMessageEnum.DebugDrawPlane:
            case MyRenderMessageEnum.DebugDrawCylinder:
            {
                m_debugDrawMessages.Enqueue(message);
            }
            break;

            case MyRenderMessageEnum.DebugCrashRenderThread:
            {
                throw new InvalidOperationException("Forced exception");
            }
                #endregion
            }
        }