public unsafe void CreateExplosionDebris(ref BoundingSphereD explosionSphere, float voxelsCountInPercent, MyVoxelMaterialDefinition voxelMaterial, MyVoxelBase voxelMap) { MatrixD matrix = MatrixD.CreateRotationX((double)MyUtils.GetRandomRadian()) * MatrixD.CreateRotationY((double)MyUtils.GetRandomRadian()); int count = this.m_voxelDebrisOffsets.Count; int num = this.m_voxelDebrisOffsets.Count; int num2 = 0; while (true) { if (num2 < num) { MyDebrisVoxel voxel = this.CreateVoxelDebris(((float)explosionSphere.Radius) * 100f, ((float)explosionSphere.Radius) * 1000f); if (voxel != null) { Vector3D result = (this.m_voxelDebrisOffsets[num2] * ((float)explosionSphere.Radius)) * 0.5780347f; Vector3D *vectordPtr1 = (Vector3D *)ref result; Vector3D.Transform(ref (Vector3D) ref vectordPtr1, ref matrix, out result); result += explosionSphere.Center; Vector3 vector = MyUtils.GetRandomVector3Normalized(); if (vector != Vector3.Zero) { (voxel.Debris as MyDebrisVoxel.MyDebrisVoxelLogic).Start(result, vector * MyUtils.GetRandomFloat(4f, 8f), voxelMaterial); } num2++; continue; } } return; } }
public unsafe int CountPointsInside(Vector3D *worldPoints, int pointCount) { MatrixD voxelTransform = PositionComp.WorldMatrixInvScaled; int pointCountInside = 0; Vector3I oldMin, oldMax; oldMin = new Vector3I(int.MaxValue); oldMax = new Vector3I(int.MinValue); for (int i = 0; i < pointCount; i++) { Vector3D local; Vector3D.Transform(ref worldPoints[i], ref voxelTransform, out local); Vector3D minRel = local + (Vector3D)(Size / 2); Vector3I min = (Vector3I)Vector3D.Floor(minRel); Vector3D.Fract(ref minRel, out minRel); min -= StorageMin; var max = min + 1; if (min != oldMin && max != oldMax) { // load only if range has changed m_tempStorage.Resize(min, max); Storage.ReadRange(m_tempStorage, MyStorageDataTypeFlags.Content, 0, ref min, ref max); oldMin = min; oldMax = max; } // Don't really need doubles but since position is in double and C# doesn't do SIMD yet, this makes little difference. var c000 = (double)m_tempStorage.Content(0, 0, 0); var c100 = (double)m_tempStorage.Content(1, 0, 0); var c010 = (double)m_tempStorage.Content(0, 1, 0); var c110 = (double)m_tempStorage.Content(1, 1, 0); var c001 = (double)m_tempStorage.Content(0, 0, 1); var c101 = (double)m_tempStorage.Content(1, 0, 1); var c011 = (double)m_tempStorage.Content(0, 1, 1); var c111 = (double)m_tempStorage.Content(1, 1, 1); c000 = c000 + (c100 - c000) * minRel.X; c010 = c010 + (c110 - c010) * minRel.X; c001 = c001 + (c101 - c001) * minRel.X; c011 = c011 + (c111 - c011) * minRel.X; c000 = c000 + (c010 - c000) * minRel.Y; c001 = c001 + (c011 - c001) * minRel.Y; c000 = c000 + (c001 - c000) * minRel.Z; //Color color = Color.Green; if (c000 >= (double)MyVoxelConstants.VOXEL_ISO_LEVEL) { pointCountInside++; //color = Color.Red; } //VRageRender.MyRenderProxy.DebugDrawText3D(worldPoints[i], c000.ToString("000.0"), color, 0.7f, false); } return(pointCountInside); }
public unsafe void GetCornersUnsafe(Vector3D *corners) { corners.X = this.Min.X; corners.Y = this.Max.Y; corners.Z = this.Max.Z; corners[1].X = this.Max.X; corners[1].Y = this.Max.Y; corners[1].Z = this.Max.Z; corners[2].X = this.Max.X; corners[2].Y = this.Min.Y; corners[2].Z = this.Max.Z; corners[3].X = this.Min.X; corners[3].Y = this.Min.Y; corners[3].Z = this.Max.Z; corners[4].X = this.Min.X; corners[4].Y = this.Max.Y; corners[4].Z = this.Min.Z; corners[5].X = this.Max.X; corners[5].Y = this.Max.Y; corners[5].Z = this.Min.Z; corners[6].X = this.Max.X; corners[6].Y = this.Min.Y; corners[6].Z = this.Min.Z; corners[7].X = this.Min.X; corners[7].Y = this.Min.Y; corners[7].Z = this.Min.Z; }
public unsafe override void GetCorners(Vector3D *corners) { LocalAABB.GetCornersUnsafe(corners); for (int i = 0; i < 8; i++) { corners[i] = Vector3D.Transform(corners[i], WorldMatrix); } }
public unsafe void DoWork() { try { //MyEntities.EntityCloseLock.AcquireShared(); if (m_renderObject == null) { return; } if (m_renderObject is MyRenderVoxelCell) { } Vector3 directionToSunNormalized = -MyRender.Sun.Direction; VisibleFromSun = false; var line2 = new LineD(m_renderObject.WorldVolume.Center, m_renderObject.WorldVolume.Center + directionToSunNormalized * MyShadowRenderer.SHADOW_MAX_OFFSET * 0.5f); var result2 = MyRender.GetAnyIntersectionWithLine(MyRender.ShadowPrunning, ref line2, m_renderObject, null, m_overlapList); VisibleFromSun |= (result2 == null); //if nothing hit, its visible from sun if (m_renderObject.FastCastShadowResolve) { return; } Vector3D *corners = stackalloc Vector3D[8]; m_renderObject.GetCorners(corners); for (int i = 0; i < 8; i++) { LineD line = new LineD(corners[i], corners[i] + directionToSunNormalized * MyShadowRenderer.SHADOW_MAX_OFFSET * 0.5f); var result = MyRender.GetAnyIntersectionWithLine(MyRender.ShadowPrunning, ref line, m_renderObject, null, m_overlapList); VisibleFromSun |= (result == null); if (VisibleFromSun) { break; } } if (!VisibleFromSun) { } } finally { /* * if (m_renderObject != null) * { * m_renderObject.OnClose -= m_entity_OnMarkForClose; * } */ // MyEntities.EntityCloseLock.ReleaseShared(); } }
private unsafe int CountPointsInside(Vector3D *worldPoints, int pointCount) { int pointCountInside = 0; Vector3I oldMin, oldMax; oldMin = new Vector3I(int.MaxValue); oldMax = new Vector3I(int.MinValue); for (int i = 0; i < pointCount; i++) { Vector3D local; Vector3I min; Vector3D minRel; MyVoxelCoordSystems.WorldPositionToLocalPosition(PositionLeftBottomCorner, ref worldPoints[i], out local); MyVoxelCoordSystems.LocalPositionToVoxelCoord(ref local, out min); MyVoxelCoordSystems.LocalPositionToVoxelCoord(ref local, out minRel); minRel -= (Vector3D)min; var max = min + 1; if (min != oldMin && max != oldMax) { // load only if range has changed m_storageCache.Resize(min, max); Storage.ReadRange(m_storageCache, MyStorageDataTypeFlags.Content, 0, ref min, ref max); oldMin = min; oldMax = max; } // Don't really need doubles but since position is in double and C# doesn't do SIMD yet, this makes little difference. var c000 = (double)m_storageCache.Content(0, 0, 0); var c100 = (double)m_storageCache.Content(1, 0, 0); var c010 = (double)m_storageCache.Content(0, 1, 0); var c110 = (double)m_storageCache.Content(1, 1, 0); var c001 = (double)m_storageCache.Content(0, 0, 1); var c101 = (double)m_storageCache.Content(1, 0, 1); var c011 = (double)m_storageCache.Content(0, 1, 1); var c111 = (double)m_storageCache.Content(1, 1, 1); c000 = c000 + (c100 - c000) * minRel.X; c010 = c010 + (c110 - c010) * minRel.X; c001 = c001 + (c101 - c001) * minRel.X; c011 = c011 + (c111 - c011) * minRel.X; c000 = c000 + (c010 - c000) * minRel.Y; c001 = c001 + (c011 - c001) * minRel.Y; c000 = c000 + (c001 - c000) * minRel.Z; //Color color = Color.Green; if (c000 >= (double)MyVoxelConstants.VOXEL_ISO_LEVEL) { pointCountInside++; //color = Color.Red; } //VRageRender.MyRenderProxy.DebugDrawText3D(worldPoints[i], c000.ToString("000.0"), color, 0.7f, false); } return(pointCountInside); }
public unsafe void GetCornersUnsafe(Vector3D *corners) { corners[0] = this.cornerArray[0]; corners[1] = this.cornerArray[1]; corners[2] = this.cornerArray[2]; corners[3] = this.cornerArray[3]; corners[4] = this.cornerArray[4]; corners[5] = this.cornerArray[5]; corners[6] = this.cornerArray[6]; corners[7] = this.cornerArray[7]; }
public override bool IsAnyAabbCornerInside(BoundingBoxD worldAabb) { MyRenderProxy.DebugDrawAABB(worldAabb, Color.White, 1f, 1f, true); unsafe { const int cornerCount = 8; Vector3D *corners = stackalloc Vector3D[cornerCount]; worldAabb.GetCornersUnsafe(corners); return(IsAnyPointInside(corners, cornerCount)); } }
public unsafe BoundingBoxD TransformSlow(ref MatrixD worldMatrix) { BoundingBoxD xd = CreateInvalid(); Vector3D * corners = (Vector3D *)stackalloc byte[(((IntPtr)8) * sizeof(Vector3D))]; this.GetCornersUnsafe(corners); for (int i = 0; i < 8; i++) { Vector3D point = Vector3D.Transform(corners[i], (MatrixD)worldMatrix); xd = xd.Include(ref point); } return(xd); }
private unsafe bool IsAnyPointInside(Vector3D *worldPoints, int pointCount) { //bool anyInside = false; for (int i = 0; i < pointCount; i++) { Vector3D local; Vector3I min; Vector3D minRel; MyVoxelCoordSystems.WorldPositionToLocalPosition(PositionLeftBottomCorner, ref worldPoints[i], out local); MyVoxelCoordSystems.LocalPositionToVoxelCoord(ref local, out min); MyVoxelCoordSystems.LocalPositionToVoxelCoord(ref local, out minRel); minRel -= (Vector3D)min; var max = min + 1; m_storageCache.Resize(min, max); // mk:TODO Could be improved to not load the same range for each corner if they are inside the same voxel. Storage.ReadRange(m_storageCache, MyStorageDataTypeFlags.Content, 0, ref min, ref max); // Don't really need doubles but since position is in double and C# doesn't do SIMD yet, this makes little difference. var c000 = (double)m_storageCache.Content(0, 0, 0); var c100 = (double)m_storageCache.Content(1, 0, 0); var c010 = (double)m_storageCache.Content(0, 1, 0); var c110 = (double)m_storageCache.Content(1, 1, 0); var c001 = (double)m_storageCache.Content(0, 0, 1); var c101 = (double)m_storageCache.Content(1, 0, 1); var c011 = (double)m_storageCache.Content(0, 1, 1); var c111 = (double)m_storageCache.Content(1, 1, 1); c000 = c000 + (c100 - c000) * minRel.X; c010 = c010 + (c110 - c010) * minRel.X; c001 = c001 + (c101 - c001) * minRel.X; c011 = c011 + (c111 - c011) * minRel.X; c000 = c000 + (c010 - c000) * minRel.Y; c001 = c001 + (c011 - c001) * minRel.Y; c000 = c000 + (c001 - c000) * minRel.Z; //Color color = Color.Green; if (c000 >= (double)MyVoxelConstants.VOXEL_ISO_LEVEL) { return(true); //anyInside = true; //color = Color.Red; } //MyRenderProxy.DebugDrawText3D(worldPoints[i], c000.ToString("000.0"), color, 0.7f, false); } return(false); //return anyInside; }
public override bool IsAnyAabbCornerInside(ref MatrixD aabbWorldTransform, BoundingBoxD aabb) { unsafe { const int cornerCount = 8; Vector3D *corners = stackalloc Vector3D[cornerCount]; aabb.GetCornersUnsafe(corners); for (int i = 0; i < cornerCount; i++) { Vector3D.Transform(ref corners[i], ref aabbWorldTransform, out corners[i]); } return(IsAnyPointInside(corners, cornerCount)); } }
private int CountCornersInside(ref MatrixD aabbWorldTransform, ref BoundingBoxD aabb) { unsafe { const int cornerCount = 8; Vector3D *corners = stackalloc Vector3D[cornerCount]; aabb.GetCornersUnsafe(corners); for (int i = 0; i < cornerCount; i++) { Vector3D.Transform(ref corners[i], ref aabbWorldTransform, out corners[i]); } return(CountPointsInside(corners, cornerCount)); } }
public unsafe BoundingBoxD Include(ref BoundingFrustumD frustum) { Vector3D *corners = (Vector3D *)stackalloc byte[(((IntPtr)8) * sizeof(Vector3D))]; frustum.GetCornersUnsafe(corners); this.Include(ref (ref Vector3D)((Vector3D) ref corners)); this.Include(ref (ref Vector3D)((Vector3D) ref (corners + 1))); this.Include(ref (ref Vector3D)((Vector3D) ref (corners + 2))); this.Include(ref (ref Vector3D)((Vector3D) ref (corners + 3))); this.Include(ref (ref Vector3D)((Vector3D) ref (corners + 4))); this.Include(ref (ref Vector3D)((Vector3D) ref (corners + 5))); this.Include(ref (ref Vector3D)((Vector3D) ref (corners + 6))); this.Include(ref (ref Vector3D)((Vector3D) ref (corners + 7))); return(this); }
public override unsafe void DebugDraw() { base.DebugDraw(); if (((this.m_aabbPhantom != null) && MyDebugDrawSettings.DEBUG_DRAW_VOXEL_MAP_AABB) && this.IsInWorld) { BoundingBoxD aabb = this.m_aabbPhantom.Aabb; aabb.Translate(this.ClusterToWorld(Vector3.Zero)); MyRenderProxy.DebugDrawAABB(aabb, Color.Orange, 1f, 1f, true, false, false); } if (MyDebugDrawSettings.DEBUG_DRAW_VOXEL_PHYSICS_PREDICTION) { foreach (IMyEntity entity in this.m_nearbyEntities) { if (!entity.MarkedForClose) { BoundingBoxD xd3; BoundingBoxD worldAABB = entity.WorldAABB; MyRenderProxy.DebugDrawAABB(worldAABB, Color.Bisque, 1f, 1f, true, false, false); MyRenderProxy.DebugDrawLine3D(this.GetWorldMatrix().Translation, worldAABB.Center, Color.Bisque, Color.BlanchedAlmond, true, false); this.GetPrediction(entity, out xd3); MyRenderProxy.DebugDrawAABB(xd3, Color.Crimson, 1f, 1f, true, false, false); } } using (IMyDebugDrawBatchAabb aabb = MyRenderProxy.DebugDrawBatchAABB(this.GetWorldMatrix(), new Color(Color.Cyan, 0.2f), true, false)) { int num = 0; foreach (KeyValuePair <MyCellCoord, MyPrecalcJobPhysicsPrefetch> pair in this.m_workTracker) { BoundingBoxD xd5; num++; MyCellCoord key = pair.Key; xd5.Min = (Vector3D)(key.CoordInLod << key.Lod); Vector3D *vectordPtr1 = (Vector3D *)ref xd5.Min; vectordPtr1[0] *= 8.0; Vector3D *vectordPtr2 = (Vector3D *)ref xd5.Min; vectordPtr2[0] -= this.m_voxelMap.SizeInMetresHalf; BoundingBoxD *xdPtr1 = (BoundingBoxD *)ref xd5; xdPtr1->Max = xd5.Min + 8f; Color?color = null; aabb.Add(ref xd5, color); if (num > 250) { break; } } } } }
public unsafe BoundingBoxD Transform(ref MatrixD worldMatrix) { BoundingBoxD oobb = BoundingBoxD.CreateInvalid(); Vector3D *temporaryCorners = stackalloc Vector3D[8]; GetCornersUnsafe((Vector3D *)temporaryCorners); for (int i = 0; i < 8; i++) { Vector3D vctTransformed = Vector3D.Transform(temporaryCorners[i], worldMatrix); oobb = oobb.Include(ref vctTransformed); } return(oobb); }
// Assuming natural order (+Y) first internal unsafe static void Draw6FacedConvex(Vector3D *vertices, Color color, float alpha) { Color cc = color; cc.A = (byte)(alpha * 255); Vector3D c = MyRender11.Environment.Matrices.CameraPosition; Vector3D v0 = vertices[0] - c, v1 = vertices[1] - c, v2 = vertices[2] - c, v3 = vertices[3] - c, v4 = vertices[4] - c, v5 = vertices[5] - c, v6 = vertices[6] - c, v7 = vertices[7] - c; DrawQuadRowWise(v0, v1, v2, v3, cc); DrawQuadRowWise(v4, v5, v6, v7, cc); DrawQuadRowWise(v0, v1, v4, v5, cc); DrawQuadRowWise(v0, v2, v4, v6, cc); DrawQuadRowWise(v2, v3, v6, v7, cc); DrawQuadRowWise(v3, v1, v7, v5, cc); }
private unsafe MatrixD CreateGlobalMatrix() { MatrixD invView = MyRender11.Environment.InvViewProjection; Vector3D *cornersWS = stackalloc Vector3D[8]; Vector3D.Transform(m_cornersCS, ref invView, cornersWS); Vector3D centroid = Vector3D.Zero; for (int cornerIndex = 0; cornerIndex < 8; ++cornerIndex) { centroid += cornersWS[cornerIndex]; } centroid /= 8f; MatrixD view = MatrixD.CreateLookAt(centroid, centroid - MyRender11.Environment.DirectionalLightDir, Vector3D.UnitY); MatrixD proj = MatrixD.CreateOrthographic(1, 1, 0, 1); return(view * proj * MyMatrixHelpers.ClipspaceToTexture); }
private unsafe void DebugDrawFrozen(MatrixD *cascadesMatrices) { Vector3D *verticesWS = stackalloc Vector3D[8]; Color[] cascadeColor = null; cascadeColor = new[] { Color.Red, Color.Green, Color.Blue, Color.Yellow, Color.Gray, Color.Orange }; var lineBatch = MyLinesRenderer.CreateBatch(); Vector3 *tmpFloatVertices = stackalloc Vector3[8]; for (int c = 0; c < m_initializedShadowCascadesCount; c++) { if (MyRenderProxy.Settings.ShadowCascadeFrozen[c]) { var inverseViewProj = MatrixD.Invert(cascadesMatrices[c]); Vector3D.Transform(m_cornersCS, ref inverseViewProj, verticesWS); for (int vertexIndex = 0; vertexIndex < 8; ++vertexIndex) { verticesWS[vertexIndex] += MyEnvironment.CameraPosition; } for (int vertexIndex = 0; vertexIndex < 8; ++vertexIndex) { tmpFloatVertices[vertexIndex] = verticesWS[vertexIndex]; } MyPrimitivesRenderer.Draw6FacedConvexZ(tmpFloatVertices, cascadeColor[c], 0.2f); lineBatch.Add6FacedConvex(tmpFloatVertices, Color.Pink); } } lineBatch.Commit(); }
public unsafe void GetBounds(Vector3D *localPoints, int pointCount, out float minHeight, out float maxHeight) { int face = -1; for (int i = 0; i < pointCount; i++) { int num3; Vector3 position = *((Vector3 *)(localPoints + i)); MyCubemapHelpers.GetCubeFace(ref position, out num3); if (face == -1) { face = num3; } } BoundingBox query = new BoundingBox(new Vector3(float.PositiveInfinity, float.PositiveInfinity, 0f), new Vector3(float.NegativeInfinity, float.NegativeInfinity, 0f)); for (int j = 0; j < pointCount; j++) { Vector2 vector2; Vector3 localPos = *((Vector3 *)(localPoints + j)); MyCubemapHelpers.CalculateTexcoordForFace(ref localPos, face, out vector2); if (vector2.X < query.Min.X) { query.Min.X = vector2.X; } if (vector2.X > query.Max.X) { query.Max.X = vector2.X; } if (vector2.Y < query.Min.Y) { query.Min.Y = vector2.Y; } if (vector2.Y > query.Max.Y) { query.Max.Y = vector2.Y; } } this.m_heightmap.Faces[face].GetBounds(ref query); minHeight = (query.Min.Z * this.m_heightRatio) + this.InnerRadius; maxHeight = (query.Max.Z * this.m_heightRatio) + this.InnerRadius; }
public unsafe bool Intersect(ref LineD line, out double startOffset, out double endOffset) { Vector3D *vectordPtr1 = (Vector3D *)ref line.From; vectordPtr1[0] -= this.m_voxelRangeMin; Vector3D *vectordPtr2 = (Vector3D *)ref line.To; vectordPtr2[0] -= this.m_voxelRangeMin; if (!this.m_octree.Intersect(ref line, out startOffset, out endOffset)) { return(false); } Vector3D *vectordPtr3 = (Vector3D *)ref line.From; vectordPtr3[0] += this.m_voxelRangeMin; Vector3D *vectordPtr4 = (Vector3D *)ref line.To; vectordPtr4[0] += this.m_voxelRangeMin; return(true); }
public unsafe bool Intersect(ref LineD line, out double startOffset, out double endOffset) { LineD ll = line; Vector3 vector = this.Shape.Center(); Vector3D *vectordPtr1 = (Vector3D *)ref ll.To; vectordPtr1[0] -= vector; Vector3D *vectordPtr2 = (Vector3D *)ref ll.From; vectordPtr2[0] -= vector; if (!this.Shape.IntersectLine(ref ll, out startOffset, out endOffset)) { return(false); } Vector3D *vectordPtr3 = (Vector3D *)ref ll.From; vectordPtr3[0] += vector; Vector3D *vectordPtr4 = (Vector3D *)ref ll.To; vectordPtr4[0] += vector; line = ll; return(true); }
private unsafe void AddEntities(float border, Vector3D originPosition, MyOrientedBoundingBoxD obb, List <BoundingBoxD> boundingBoxes, List <MyVoxelMap> trackedEntities) { Vector3D *vectordPtr1 = (Vector3D *)ref obb.HalfExtent; vectordPtr1[0] += new Vector3D((double)border, 0.0, (double)border); BoundingBoxD aABB = obb.GetAABB(); List <VRage.Game.Entity.MyEntity> result = new List <VRage.Game.Entity.MyEntity>(); MyGamePruningStructure.GetAllEntitiesInBox(ref aABB, result, MyEntityQueryType.Both); if (result.Count <VRage.Game.Entity.MyEntity>(e => (e is MyCubeGrid)) > 0) { this.m_lastGridsInfo.Clear(); this.m_lastIntersectedGridsInfoCubes.Clear(); } foreach (VRage.Game.Entity.MyEntity entity in result) { using (entity.Pin()) { if (entity.MarkedForClose) { continue; } MyCubeGrid grid = entity as MyCubeGrid; if (grid != null) { bool isStatic = grid.IsStatic; } MyVoxelMap item = entity as MyVoxelMap; if (item != null) { trackedEntities.Add(item); this.AddVoxelVertices(item, border, originPosition, obb, boundingBoxes); } } } }
private unsafe void AddVoxelMesh(MyVoxelBase voxelBase, IMyStorage storage, Dictionary <Vector3I, MyIsoMesh> cache, float border, Vector3D originPosition, MyOrientedBoundingBoxD obb, List <BoundingBoxD> bbList) { Vector3I vectori3; Vector3I vectori4; bool flag = cache != null; if (flag) { this.CheckCacheValidity(); } Vector3D *vectordPtr1 = (Vector3D *)ref obb.HalfExtent; vectordPtr1[0] += new Vector3D((double)border, 0.0, (double)border); BoundingBoxD aABB = obb.GetAABB(); int num = (int)Math.Round((double)(aABB.HalfExtents.Max() * 2.0)); BoundingBoxD *xdPtr1 = (BoundingBoxD *)ref aABB; xdPtr1 = (BoundingBoxD *)new BoundingBoxD(aABB.Min, aABB.Min + num); ((BoundingBoxD *)ref aABB).Translate(obb.Center - aABB.Center); bbList.Add(new BoundingBoxD(aABB.Min, aABB.Max)); aABB = aABB.TransformFast(voxelBase.PositionComp.WorldMatrixInvScaled); aABB.Translate(voxelBase.SizeInMetresHalf); Vector3I voxelCoord = Vector3I.Round(aABB.Min); Vector3I vectori2 = (Vector3I)(voxelCoord + num); MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref voxelCoord, out vectori3); MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref vectori2, out vectori4); MyOrientedBoundingBoxD xd2 = obb; xd2.Transform(voxelBase.PositionComp.WorldMatrixInvScaled); Vector3D *vectordPtr2 = (Vector3D *)ref xd2.Center; vectordPtr2[0] += voxelBase.SizeInMetresHalf; Vector3I_RangeIterator iterator = new Vector3I_RangeIterator(ref vectori3, ref vectori4); MyCellCoord coord = new MyCellCoord { Lod = 0 }; int num2 = 0; Vector3 offset = (Vector3)(originPosition - voxelBase.PositionLeftBottomCorner); Vector3 up = -Vector3.Normalize(MyGravityProviderSystem.CalculateTotalGravityInPoint(originPosition)); Matrix rotation = Matrix.CreateFromQuaternion(Quaternion.Inverse(Quaternion.CreateFromForwardUp(Vector3.CalculatePerpendicularVector(up), up))); Matrix orientation = (Matrix)voxelBase.PositionComp.WorldMatrix.GetOrientation(); while (iterator.IsValid()) { BoundingBox box; MyIsoMesh mesh; if (flag && cache.TryGetValue(iterator.Current, out mesh)) { if (mesh != null) { this.AddMeshTriangles(mesh, offset, rotation, orientation); } iterator.MoveNext(); continue; } coord.CoordInLod = iterator.Current; MyVoxelCoordSystems.GeometryCellCoordToLocalAABB(ref coord.CoordInLod, out box); if (!xd2.Intersects(ref box)) { num2++; iterator.MoveNext(); } else { BoundingBoxD item = new BoundingBoxD(box.Min, box.Max).Translate(-voxelBase.SizeInMetresHalf); bbList.Add(item); Vector3I lodVoxelMin = (coord.CoordInLod * 8) - 1; MyIsoMesh mesh2 = MyPrecalcComponent.IsoMesher.Precalc(storage, 0, lodVoxelMin, (Vector3I)(((lodVoxelMin + 8) + 1) + 1), MyStorageDataTypeFlags.Content, 0); if (flag) { cache[iterator.Current] = mesh2; } if (mesh2 != null) { this.AddMeshTriangles(mesh2, offset, rotation, orientation); } iterator.MoveNext(); } } }
public static void StoreToVector(this Vector256 <double> vector, Vector3D *destination) => vector.ToVector3D(&destination->X);
public static Vector256 <double> ToVector256(Vector3D *p) => Vector.FromVector3D((double *)p);
public override unsafe void Draw() { List <MyPhysics.HitInfo> .Enumerator enumerator2; base.Draw(); foreach (MyCubeBlock block in this.m_grid.BlocksForDraw) { if (MyRenderProxy.VisibleObjectsRead.Contains(block.Render.RenderObjectIDs[0])) { block.Render.Draw(); } } if ((MyCubeGrid.ShowCenterOfMass && (!this.IsStatic && (base.Container.Entity.Physics != null))) && base.Container.Entity.Physics.HasRigidBody) { MatrixD worldMatrix = base.Container.Entity.Physics.GetWorldMatrix(); Vector3D centerOfMassWorld = base.Container.Entity.Physics.CenterOfMassWorld; Vector3D position = MySector.MainCamera.Position; float num = Vector3.Distance((Vector3)position, (Vector3)centerOfMassWorld); bool flag = false; if (num < 30f) { flag = true; } else if (num < 200f) { flag = true; MyPhysics.CastRay(position, centerOfMassWorld, m_tmpHitList, 0x10); using (enumerator2 = m_tmpHitList.GetEnumerator()) { while (enumerator2.MoveNext()) { if (!ReferenceEquals(enumerator2.Current.HkHitInfo.GetHitEntity(), this)) { flag = false; break; } } } m_tmpHitList.Clear(); } if (flag) { float num2 = MathHelper.Lerp((float)1f, (float)9f, (float)(num / 200f)); MyStringId id = ID_WEAPON_LASER_IGNORE_DEPTH; Vector4 color = Color.Yellow.ToVector4(); float thickness = 0.02f * num2; MySimpleObjectDraw.DrawLine(centerOfMassWorld - ((worldMatrix.Up * 0.5) * num2), centerOfMassWorld + ((worldMatrix.Up * 0.5) * num2), new MyStringId?(id), ref color, thickness, MyBillboard.BlendTypeEnum.AdditiveTop); MySimpleObjectDraw.DrawLine(centerOfMassWorld - ((worldMatrix.Forward * 0.5) * num2), centerOfMassWorld + ((worldMatrix.Forward * 0.5) * num2), new MyStringId?(id), ref color, thickness, MyBillboard.BlendTypeEnum.AdditiveTop); MySimpleObjectDraw.DrawLine(centerOfMassWorld - ((worldMatrix.Right * 0.5) * num2), centerOfMassWorld + ((worldMatrix.Right * 0.5) * num2), new MyStringId?(id), ref color, thickness, MyBillboard.BlendTypeEnum.AdditiveTop); MyTransparentGeometry.AddBillboardOriented(ID_RED_DOT_IGNORE_DEPTH, Color.White.ToVector4(), centerOfMassWorld, MySector.MainCamera.LeftVector, MySector.MainCamera.UpVector, 0.1f * num2, MyBillboard.BlendTypeEnum.AdditiveTop, -1, 0f); } } if (MyCubeGrid.ShowGridPivot) { MatrixD worldMatrix = base.Container.Entity.WorldMatrix; Vector3D translation = worldMatrix.Translation; Vector3D position = MySector.MainCamera.Position; float num4 = Vector3.Distance((Vector3)position, (Vector3)translation); bool flag2 = false; if (num4 < 30f) { flag2 = true; } else if (num4 < 200f) { flag2 = true; MyPhysics.CastRay(position, translation, m_tmpHitList, 0x10); using (enumerator2 = m_tmpHitList.GetEnumerator()) { while (enumerator2.MoveNext()) { if (!ReferenceEquals(enumerator2.Current.HkHitInfo.GetHitEntity(), this)) { flag2 = false; break; } } } m_tmpHitList.Clear(); } if (flag2) { float num5 = MathHelper.Lerp((float)1f, (float)9f, (float)(num4 / 200f)); MyStringId id2 = ID_WEAPON_LASER_IGNORE_DEPTH; float thickness = 0.02f * num5; Vector4 color = Color.Green.ToVector4(); MySimpleObjectDraw.DrawLine(translation, translation + ((worldMatrix.Up * 0.5) * num5), new MyStringId?(id2), ref color, thickness, MyBillboard.BlendTypeEnum.Standard); color = Color.Blue.ToVector4(); MySimpleObjectDraw.DrawLine(translation, translation + ((worldMatrix.Forward * 0.5) * num5), new MyStringId?(id2), ref color, thickness, MyBillboard.BlendTypeEnum.Standard); color = Color.Red.ToVector4(); MySimpleObjectDraw.DrawLine(translation, translation + ((worldMatrix.Right * 0.5) * num5), new MyStringId?(id2), ref color, thickness, MyBillboard.BlendTypeEnum.Standard); MyTransparentGeometry.AddBillboardOriented(ID_RED_DOT_IGNORE_DEPTH, Color.White.ToVector4(), translation, MySector.MainCamera.LeftVector, MySector.MainCamera.UpVector, 0.1f * num5, MyBillboard.BlendTypeEnum.Standard, -1, 0f); MyRenderProxy.DebugDrawAxis(worldMatrix, 0.5f, false, false, false); } } if (!MyCubeGrid.ShowStructuralIntegrity) { if ((this.m_grid.StructuralIntegrity != null) && this.m_grid.StructuralIntegrity.EnabledOnlyForDraw) { this.m_grid.CloseStructuralIntegrity(); } } else if (this.m_grid.StructuralIntegrity != null) { this.m_grid.StructuralIntegrity.Draw(); } else if (MyFakes.ENABLE_STRUCTURAL_INTEGRITY) { this.m_grid.CreateStructuralIntegrity(); if (this.m_grid.StructuralIntegrity != null) { this.m_grid.StructuralIntegrity.EnabledOnlyForDraw = true; } } if (MyFakes.ENABLE_ATMOSPHERIC_ENTRYEFFECT) { this.DrawAtmosphericEntryEffect(); } if (this.m_grid.MarkedAsTrash) { BoundingBoxD localAABB = this.m_grid.PositionComp.LocalAABB; Vector3D * vectordPtr1 = (Vector3D *)ref localAABB.Max; vectordPtr1[0] += 0.2f; Vector3D *vectordPtr2 = (Vector3D *)ref localAABB.Min; vectordPtr2[0] -= 0.20000000298023224; MatrixD worldMatrix = this.m_grid.PositionComp.WorldMatrix; Color red = Color.Red; red.A = (byte)(((100.0 * (Math.Sin((double)(((float)this.m_grid.TrashHighlightCounter) / 10f)) + 1.0)) / 2.0) + 100.0); red.R = (byte)(((200.0 * (Math.Sin((double)(((float)this.m_grid.TrashHighlightCounter) / 10f)) + 1.0)) / 2.0) + 50.0); Color * colorPtr1 = (Color *)ref red; MyStringId?faceMaterial = null; faceMaterial = null; MySimpleObjectDraw.DrawTransparentBox(ref worldMatrix, ref localAABB, ref (Color) ref colorPtr1, ref red, MySimpleObjectRasterizer.SolidAndWireframe, 1, 0.008f, faceMaterial, faceMaterial, false, -1, MyBillboard.BlendTypeEnum.LDR, 1f, null); } }
/// <summary> /// Creates shadowmap queries and appends them to the provided list /// </summary> internal unsafe void PrepareQueries(List <MyShadowmapQuery> appendShadowmapQueries) { Debug.Assert(appendShadowmapQueries != null, "Shadowmap query list cannot be null!"); if (!MyRenderProxy.Settings.EnableShadows || !MyRender11.DebugOverrides.Shadows) { return; } MyImmediateRC.RC.BeginProfilingBlock("PrepareCascades"); MyImmediateRC.RC.DeviceContext.CopyResource(m_cascadeShadowmapArray.Resource, m_cascadeShadowmapBackup.Resource); bool stabilize = true; const float DirectionDifferenceThreshold = 0.0175f; float shadowChangeDelayMultiplier = 180; for (int cascadeIndex = 0; cascadeIndex < m_initializedShadowCascadesCount; ++cascadeIndex) { ++m_shadowCascadeFramesSinceLightUpdate[cascadeIndex]; if (m_shadowCascadeFramesSinceLightUpdate[cascadeIndex] > cascadeIndex * shadowChangeDelayMultiplier || MyRender11.Environment.DirectionalLightDir.Dot(m_shadowCascadeLightDirections[cascadeIndex]) < (1 - DirectionDifferenceThreshold)) { m_shadowCascadeLightDirections[cascadeIndex] = MyRender11.Environment.DirectionalLightDir; m_shadowCascadeFramesSinceLightUpdate[cascadeIndex] = 0; } } var globalMatrix = CreateGlobalMatrix(); float cascadesNearClip = 1f; float backOffset = MyRender11.RenderSettings.ShadowQuality.BackOffset(); float shadowmapSize = MyRender11.RenderSettings.ShadowQuality.ShadowCascadeResolution(); for (int cascadeIndex = 0; cascadeIndex < ShadowCascadeSplitDepths.Length; ++cascadeIndex) { ShadowCascadeSplitDepths[cascadeIndex] = MyRender11.RenderSettings.ShadowQuality.ShadowCascadeSplit(cascadeIndex); } double unitWidth = 1.0 / MyRender11.Environment.Projection.M11; double unitHeight = 1.0 / MyRender11.Environment.Projection.M22; Vector3D *untransformedVertices = stackalloc Vector3D[4]; untransformedVertices[0] = new Vector3D(-unitWidth, -unitHeight, -1); untransformedVertices[1] = new Vector3D(-unitWidth, unitHeight, -1); untransformedVertices[2] = new Vector3D(unitWidth, unitHeight, -1); untransformedVertices[3] = new Vector3D(unitWidth, -unitHeight, -1); MatrixD *cascadesMatrices = stackalloc MatrixD[MaxShadowCascades]; for (int cascadeIndex = 0; cascadeIndex < m_initializedShadowCascadesCount; ++cascadeIndex) { for (int vertexIndex = 0; vertexIndex < 4; ++vertexIndex) { m_frustumVerticesWS[vertexIndex] = untransformedVertices[vertexIndex] * ShadowCascadeSplitDepths[cascadeIndex]; m_frustumVerticesWS[vertexIndex + 4] = untransformedVertices[vertexIndex] * ShadowCascadeSplitDepths[cascadeIndex + 1]; } bool skipCascade = MyCommon.FrameCounter % (ulong)m_shadowCascadeUpdateIntervals[cascadeIndex].Item1 != (ulong)m_shadowCascadeUpdateIntervals[cascadeIndex].Item2; bool forceUpdate = ShadowCascadeSplitDepths[cascadeIndex] > 1000f && Vector3D.DistanceSquared(m_shadowCascadeUpdatePositions[cascadeIndex], MyRender11.Environment.CameraPosition) > Math.Pow(1000, 2); // if (!forceUpdate && skipCascade && !MyRenderProxy.Settings.UpdateCascadesEveryFrame) { continue; } if (MyRenderProxy.Settings.ShadowCascadeFrozen[cascadeIndex]) { continue; } m_shadowCascadeUpdatePositions[cascadeIndex] = MyRender11.Environment.CameraPosition; MatrixD invView = MyRender11.Environment.InvView; Vector3D.Transform(m_frustumVerticesWS, ref invView, m_frustumVerticesWS); var bSphere = BoundingSphereD.CreateFromPoints(m_frustumVerticesWS); if (stabilize) { bSphere.Center = bSphere.Center.Round(); bSphere.Radius = Math.Ceiling(bSphere.Radius); } var shadowCameraPosWS = bSphere.Center + m_shadowCascadeLightDirections[cascadeIndex] * (bSphere.Radius + cascadesNearClip); var lightView = VRageMath.MatrixD.CreateLookAt(shadowCameraPosWS, shadowCameraPosWS - m_shadowCascadeLightDirections[cascadeIndex], Math.Abs(Vector3.UnitY.Dot(m_shadowCascadeLightDirections[cascadeIndex])) < 0.99f ? Vector3.UnitY : Vector3.UnitX); var offset = bSphere.Radius + cascadesNearClip + backOffset; Vector3D vMin = new Vector3D(-bSphere.Radius, -bSphere.Radius, cascadesNearClip); Vector3D vMax = new Vector3D(bSphere.Radius, bSphere.Radius, offset + bSphere.Radius); var cascadeProjection = MatrixD.CreateOrthographicOffCenter(vMin.X, vMax.X, vMin.Y, vMax.Y, vMax.Z, vMin.Z); cascadesMatrices[cascadeIndex] = lightView * cascadeProjection; var transformed = Vector3D.Transform(Vector3D.Zero, cascadesMatrices[cascadeIndex]) * shadowmapSize / 2; var smOffset = (transformed.Round() - transformed) * 2 / shadowmapSize; // stabilize 1st cascade only if (stabilize) { cascadeProjection.M41 += smOffset.X; cascadeProjection.M42 += smOffset.Y; cascadesMatrices[cascadeIndex] = lightView * cascadeProjection; } var inverseCascadeMatrix = MatrixD.Invert(cascadesMatrices[cascadeIndex]); var corner0 = Vector3D.Transform(Vector3D.Transform(new Vector3D(-1, -1, 0), inverseCascadeMatrix), globalMatrix); var corner1 = Vector3D.Transform(Vector3D.Transform(new Vector3D(1, 1, 1), inverseCascadeMatrix), globalMatrix); var diameter = corner1 - corner0; var cascadeScale = 1f / diameter; ShadowCascadeScales[cascadeIndex] = new Vector4D(cascadeScale, 0); var query = new MyShadowmapQuery(); query.DepthBuffer = m_cascadeShadowmapArray.SubresourceDsv(cascadeIndex); query.Viewport = new MyViewport(shadowmapSize, shadowmapSize); m_cascadeInfo[cascadeIndex].WorldCameraOffsetPosition = MyRender11.Environment.CameraPosition; m_cascadeInfo[cascadeIndex].WorldToProjection = cascadesMatrices[cascadeIndex]; // todo: skip translation, recalculate matrix in local space, keep world space matrix only for bounding frustum m_cascadeInfo[cascadeIndex].LocalToProjection = Matrix.CreateTranslation(MyRender11.Environment.CameraPosition) * cascadesMatrices[cascadeIndex]; query.ProjectionInfo = m_cascadeInfo[cascadeIndex]; query.ProjectionDir = m_shadowCascadeLightDirections[cascadeIndex]; query.ProjectionFactor = (float)(shadowmapSize * shadowmapSize / (bSphere.Radius * bSphere.Radius * 4)); query.QueryType = MyFrustumEnum.ShadowCascade; query.CascadeIndex = cascadeIndex; appendShadowmapQueries.Add(query); } DebugProcessFrustrums(); FillConstantBuffer(m_csmConstants); MyImmediateRC.RC.EndProfilingBlock(); }
private unsafe void RasterSectorsForCollision(MyEntity entity) { if (!(entity is MyCubeGrid)) { return; } BoundingBoxD range = entity.PositionComp.WorldAABB; range.Inflate(8); range.Translate(-PlanetTranslation); Vector2I top = new Vector2I(1 << m_clipmaps[0].Depth) - 1; Vector3D *pos = stackalloc Vector3D[8]; range.GetCornersUnsafe(pos); // bitmask for faces, 7th bit is simple bit int markedFaces = 0; int firstFace = 0; for (var i = 0; i < 8; ++i) { Vector3D copy = pos[i]; int index = MyPlanetCubemapHelper.FindCubeFace(ref copy); firstFace = index; index = 1 << index; if ((markedFaces & ~index) != 0) { markedFaces |= 0x40; } markedFaces |= index; } // This way we can ensure a single code path. int startFace = 0; int endFace = 5; // If we only encounter one face we narrow it down. if ((markedFaces & 0x40) == 0) { startFace = endFace = firstFace; } for (int face = startFace; face <= endFace; ++face) { if (((1 << face) & markedFaces) == 0) { continue; } // Offset var offset = 1 << m_clipmaps[face].Depth - 1; BoundingBox2D bounds = BoundingBox2D.CreateInvalid(); for (int i = 0; i < 8; ++i) { Vector3D copy = pos[i]; Vector2D normCoords; MyPlanetCubemapHelper.ProjectForFace(ref copy, face, out normCoords); bounds.Include(normCoords); } bounds.Min += 1; bounds.Min *= offset; bounds.Max += 1; bounds.Max *= offset; // Calculate bounds in sectors. var start = new Vector2I((int)bounds.Min.X, (int)bounds.Min.Y); var end = new Vector2I((int)bounds.Max.X, (int)bounds.Max.Y); Vector2I.Max(ref start, ref Vector2I.Zero, out start); Vector2I.Min(ref end, ref top, out end); for (int x = start.X; x <= end.X; ++x) { for (int y = start.Y; y <= end.Y; ++y) { long sect = MyPlanetSectorId.MakeSectorId(x, y, face); List <MyOrientedBoundingBoxD> boxes; if (!m_obstructorsPerSector.TryGetValue(sect, out boxes)) { boxes = new List <MyOrientedBoundingBoxD>(); m_obstructorsPerSector.Add(sect, boxes); } var bb = entity.PositionComp.LocalAABB; bb.Inflate(8); // inflate by 8m to increase the likellyhood of overlap with trees' roots. boxes.Add(new MyOrientedBoundingBoxD((BoundingBoxD)bb, entity.PositionComp.WorldMatrix)); } } } }
// Iterate over sector boxes in a range. // TODO: Dumb version of this for small boxes private unsafe void RasterSectorsForPhysics(BoundingBoxD range) { range.InflateToMinimum(EnvironmentDefinition.SectorSize); Vector2I top = new Vector2I(1 << m_clipmaps[0].Depth) - 1; Vector3D *pos = stackalloc Vector3D[8]; range.GetCornersUnsafe(pos); // bitmask for faces, 7th bit is simple bit int markedFaces = 0; int firstFace = 0; for (var i = 0; i < 8; ++i) { Vector3D copy = pos[i]; int index = MyPlanetCubemapHelper.FindCubeFace(ref copy); firstFace = index; index = 1 << index; if ((markedFaces & ~index) != 0) { markedFaces |= 0x40; } markedFaces |= index; } // This way we can ensure a single code path. int startFace = 0; int endFace = 5; // If we only encounter one face we narrow it down. if ((markedFaces & 0x40) == 0) { startFace = endFace = firstFace; } for (int face = startFace; face <= endFace; ++face) { if (((1 << face) & markedFaces) == 0) { continue; } double size = m_clipmaps[face].LeafSize; // Offset var offset = 1 << m_clipmaps[face].Depth - 1; BoundingBox2D bounds = BoundingBox2D.CreateInvalid(); for (int i = 0; i < 8; ++i) { Vector3D copy = pos[i]; Vector2D normCoords; MyPlanetCubemapHelper.ProjectForFace(ref copy, face, out normCoords); bounds.Include(normCoords); } bounds.Min += 1; bounds.Min *= offset; bounds.Max += 1; bounds.Max *= offset; // Calculate bounds in sectors. var start = new Vector2I((int)bounds.Min.X, (int)bounds.Min.Y); var end = new Vector2I((int)bounds.Max.X, (int)bounds.Max.Y); Vector2I.Max(ref start, ref Vector2I.Zero, out start); Vector2I.Min(ref end, ref top, out end); for (int x = start.X; x <= end.X; ++x) { for (int y = start.Y; y <= end.Y; ++y) { EnsurePhysicsSector(x, y, face); } } } }
private unsafe void MarkCascadesInStencil(MyProjectionInfo[] cascadeInfo) { MyGpuProfiler.IC_BeginBlock("MarkCascadesInStencil"); //RC.SetRS(MyRasterizerState.CullCW); MyRenderContext renderContext = MyRenderContext.Immediate; renderContext.DeviceContext.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList; renderContext.SetVB(0, m_cascadesBoundingsVertices.Buffer, m_cascadesBoundingsVertices.Stride); renderContext.SetIB(m_cubeIB.Buffer, m_cubeIB.Format); renderContext.SetIL(m_inputLayout); renderContext.DeviceContext.Rasterizer.SetViewport(0, 0, MyRender11.ViewportResolution.X, MyRender11.ViewportResolution.Y); renderContext.SetCB(MyCommon.FRAME_SLOT, MyCommon.FrameConstants); renderContext.BindDepthRT(MyGBuffer.Main.DepthStencil, DepthStencilAccess.DepthReadOnly, null); renderContext.SetVS(m_markVS); renderContext.SetPS(m_markPS); const int vertexCount = 8; Vector3D *frustumVerticesSS = stackalloc Vector3D[vertexCount]; frustumVerticesSS[0] = new Vector3D(-1, -1, 0); frustumVerticesSS[1] = new Vector3D(-1, 1, 0); frustumVerticesSS[2] = new Vector3D(1, 1, 0); frustumVerticesSS[3] = new Vector3D(1, -1, 0); frustumVerticesSS[4] = new Vector3D(-1, -1, 1); frustumVerticesSS[5] = new Vector3D(-1, 1, 1); frustumVerticesSS[6] = new Vector3D(1, 1, 1); frustumVerticesSS[7] = new Vector3D(1, -1, 1); Vector3D *lightVertices = stackalloc Vector3D[vertexCount]; Vector3 * tmpFloatVertices = stackalloc Vector3[vertexCount]; var mapping = MyMapping.MapDiscard(m_cascadesBoundingsVertices.Buffer); for (int cascadeIndex = 0; cascadeIndex < MyRender11.Settings.ShadowCascadeCount; ++cascadeIndex) { var inverseViewProj = MatrixD.Invert(cascadeInfo[cascadeIndex].CurrentLocalToProjection); for (int arrayIndex = 0; arrayIndex < vertexCount; ++arrayIndex) { Vector3D.Transform(ref frustumVerticesSS[arrayIndex], ref inverseViewProj, out lightVertices[arrayIndex]); tmpFloatVertices[arrayIndex] = lightVertices[arrayIndex]; } for (int arrayIndex = 0; arrayIndex < vertexCount; ++arrayIndex) { mapping.WriteAndPosition(ref tmpFloatVertices[arrayIndex]); } } mapping.Unmap(); for (int cascadeIndex = 0; cascadeIndex < MyRender11.Settings.ShadowCascadeCount; ++cascadeIndex) { renderContext.SetDS(MyDepthStencilState.MarkIfInsideCascade[cascadeIndex], 1 << cascadeIndex); // mark ith bit on depth near renderContext.DeviceContext.DrawIndexed(36, 0, 8 * cascadeIndex); } renderContext.BindDepthRT(null, DepthStencilAccess.DepthReadOnly, null); renderContext.SetDS(null); renderContext.SetRS(null); MyGpuProfiler.IC_EndBlock(); }