internal static bool CheckSelfHit(Weapon w, ref Vector3D targetPos, ref Vector3D testPos, out Vector3D predictedMuzzlePos) { var testLine = new LineD(targetPos, testPos); predictedMuzzlePos = testLine.To + (-testLine.Direction * w.MuzzleDistToBarrelCenter); var ai = w.Comp.Ai; var localPredictedPos = Vector3I.Round(Vector3D.Transform(predictedMuzzlePos, ai.MyGrid.PositionComp.WorldMatrixNormalizedInv) * ai.MyGrid.GridSizeR); MyCube cube; var noCubeAtPosition = !ai.MyGrid.TryGetCube(localPredictedPos, out cube); if (noCubeAtPosition || cube.CubeBlock == w.Comp.MyCube.SlimBlock) { var noCubeInLine = !ai.MyGrid.GetIntersectionWithLine(ref testLine, ref ai.GridHitInfo); var noCubesInLineOrHitSelf = noCubeInLine || ai.GridHitInfo.Position == w.Comp.MyCube.Position; if (noCubesInLineOrHitSelf) { w.System.Session.Physics.CastRay(predictedMuzzlePos, testLine.From, out w.LastHitInfo, CollisionLayers.DefaultCollisionLayer); if (w.LastHitInfo != null && w.LastHitInfo.HitEntity == ai.MyGrid) { return(true); } } } else { return(true); } return(false); }
public static IMySlimBlock Block(this IHitInfo hit, Vector3 rayDirection, float maxPrediction = 10f) { if (hit == null) { return(null); } var fat = hit.HitEntity as IMyCubeBlock; if (fat != null) { return(fat.SlimBlock); } var grid = hit.HitEntity as IMyCubeGrid; if (grid == null) { return(null); } var local = Vector3.Transform(hit.Position, grid.WorldMatrixNormalizedInv); var test = grid.GetCubeBlock(Vector3I.Round(local / grid.GridSize)); if (test != null) { return(test); } return(grid.FirstBlock(hit.Position, hit.Position + maxPrediction * rayDirection)); }
protected override void Init(MyObjectBuilder_DefinitionBase ob) { base.Init(ob); var objectBuilder = ob as MyObjectBuilder_BlockNavigationDefinition; Debug.Assert(ob != null); if (ob == null) { return; } if (objectBuilder.NoEntry || objectBuilder.Triangles == null) { NoEntry = true; } else { NoEntry = false; var newMesh = new MyGridNavigationMesh(null, null, objectBuilder.Triangles.Length); Vector3I maxPos = objectBuilder.Size - Vector3I.One - objectBuilder.Center; Vector3I minPos = -(Vector3I)(objectBuilder.Center); foreach (var triOb in objectBuilder.Triangles) { Vector3 pa = (Vector3)triOb.Points[0]; Vector3 pb = (Vector3)triOb.Points[1]; Vector3 pc = (Vector3)triOb.Points[2]; var tri = newMesh.AddTriangle(ref pa, ref pb, ref pc); var center = (pa + pb + pc) / 3.0f; // We want to move the triangle vertices more towards the triangle center to ensure correct calculation of containing cube Vector3 cvA = (center - pa) * 0.0001f; Vector3 cvB = (center - pb) * 0.0001f; Vector3 cvC = (center - pc) * 0.0001f; Vector3I gridPosA = Vector3I.Round(pa + cvA); Vector3I gridPosB = Vector3I.Round(pb + cvB); Vector3I gridPosC = Vector3I.Round(pc + cvC); Vector3I.Clamp(ref gridPosA, ref minPos, ref maxPos, out gridPosA); Vector3I.Clamp(ref gridPosB, ref minPos, ref maxPos, out gridPosB); Vector3I.Clamp(ref gridPosC, ref minPos, ref maxPos, out gridPosC); Vector3I min, max; Vector3I.Min(ref gridPosA, ref gridPosB, out min); Vector3I.Min(ref min, ref gridPosC, out min); Vector3I.Max(ref gridPosA, ref gridPosB, out max); Vector3I.Max(ref max, ref gridPosC, out max); Vector3I pos = min; for (var it = new Vector3I.RangeIterator(ref min, ref max); it.IsValid(); it.GetNext(out pos)) { newMesh.RegisterTriangle(tri, ref pos); } } m_mesh = newMesh; } }
private MyHighLevelPrimitive GetClosestHighLevelPrimitive(ref Vector3 point, ref float closestDistanceSq) { MyHighLevelPrimitive primitive = null; m_tmpIntList.Clear(); Vector3I vectori = Vector3I.Round((point + (this.m_voxelMap.PositionComp.GetPosition() - this.m_voxelMap.PositionLeftBottomCorner)) / this.m_cellSize); for (int i = 0; i < 8; i++) { Vector3I coordInLod = (Vector3I)(vectori + m_cornerOffsets[i]); ulong packedCoord = new MyCellCoord(0, coordInLod).PackId64(); this.m_higherLevelHelper.CollectComponents(packedCoord, m_tmpIntList); } foreach (int num3 in m_tmpIntList) { MyHighLevelPrimitive primitive2 = this.m_higherLevel.GetPrimitive(num3); if (primitive2 != null) { float num4 = Vector3.DistanceSquared(primitive2.Position, point); if (num4 < closestDistanceSq) { closestDistanceSq = num4; primitive = primitive2; } } } m_tmpIntList.Clear(); return(primitive); }
private Vector3I FindTriangleCube(int triIndex, ref Vector3I edgePositionA, ref Vector3I edgePositionB) { Vector3I min, max; Vector3I.Min(ref edgePositionA, ref edgePositionB, out min); Vector3I.Max(ref edgePositionA, ref edgePositionB, out max); min = Vector3I.Round(new Vector3(min) / 256.0f - Vector3.Half); max = Vector3I.Round(new Vector3(max) / 256.0f + Vector3.Half); for (var it = new Vector3I.RangeIterator(ref min, ref max); it.IsValid(); it.GetNext(out min)) { List <int> list; m_smallTriangleRegistry.TryGetValue(min, out list); if (list == null) { continue; } if (list.Contains(triIndex)) { return(min); } } Debug.Assert(false, "Could not find navmesh triangle cube. Shouldn't get here!"); return(Vector3I.Zero); }
private MyNavigationTriangle GetClosestNavigationTriangle(ref Vector3 point, ref float closestDistanceSq) { MyNavigationTriangle triangle = null; Vector3I vectori = Vector3I.Round((point + (this.m_voxelMap.PositionComp.GetPosition() - this.m_voxelMap.PositionLeftBottomCorner)) / this.m_cellSize); for (int i = 0; i < 8; i++) { Vector3I position = (Vector3I)(vectori + m_cornerOffsets[i]); if (this.m_processedCells.Contains(position)) { ulong packedCellCoord = new MyCellCoord(0, position).PackId64(); MyIntervalList list = this.m_higherLevelHelper.TryGetTriangleList(packedCellCoord); if (list != null) { MyIntervalList.Enumerator enumerator = list.GetEnumerator(); while (enumerator.MoveNext()) { int current = enumerator.Current; MyNavigationTriangle triangle2 = base.GetTriangle(current); float num4 = Vector3.DistanceSquared(triangle2.Center, point); if (num4 < closestDistanceSq) { closestDistanceSq = num4; triangle = triangle2; } } } } } return(triangle); }
private int GetDivideIndex(ref Vector3I renderCellCoord) { // TODO: Optimize int divideIndex = 0; if (m_lodDivisions > 1) { BoundingBoxD lodAabb = m_boundingBoxes.GetAabb(m_boundingBoxes.GetRoot()); Vector3I test = Vector3I.Round(lodAabb.Size / (double)MyVoxelCoordSystems.RenderCellSizeInMeters(m_lod)); //Vector3I lodSizeMinusOne = m_parentClipmap.LodSizeMinusOne(m_lod); //Vector3I lodSize = lodSizeMinusOne + Vector3I.One; Vector3I lodSize = test; Vector3I lodSizeMinusOne = test - 1; Vector3I lodDivision = Vector3I.One * (m_lodDivisions - 1); var cellIterator = new Vector3I.RangeIterator(ref Vector3I.Zero, ref lodDivision); for (; cellIterator.IsValid(); cellIterator.MoveNext()) { Vector3I currentDivision = cellIterator.Current; Vector3I min = currentDivision * lodSize / m_lodDivisions; Vector3I max = (currentDivision + Vector3I.One) * lodSize / m_lodDivisions; if (renderCellCoord.IsInsideInclusive(ref min, ref max)) { break; } } Debug.Assert(cellIterator.IsValid(), "Valid division index not found!"); Vector3I foundCell = cellIterator.Current; divideIndex = GetDivideIndexFromMergeCell(ref foundCell); } return(divideIndex); }
void AddConvexShape(MySlimBlock block, bool applySkeleton) { ProfilerShort.Begin("AddConvexShape"); Debug.Assert(block.Min == block.Max, "Calculation assume that cube blocks have size 1x1x1"); Debug.Assert(block.BlockDefinition.BlockTopology == MyBlockTopology.Cube, "Convex shape is available only for cube block"); Debug.Assert(block.BlockDefinition.CubeDefinition != null, "No cube definition! Only armor can be convex"); m_tmpHelperVerts.Clear(); var blockPos = block.Min * block.CubeGrid.GridSize; var bonePos = block.Min * MyGridSkeleton.BoneDensity + 1; var skeleton = block.CubeGrid.Skeleton; Vector3 pointBone; foreach (var point in MyBlockVerticesCache.GetBlockVertices(block.BlockDefinition.CubeDefinition.CubeTopology, block.Orientation)) { var pointBonePos = bonePos + Vector3I.Round(point); var vert = point * block.CubeGrid.GridSizeHalf; if (skeleton.TryGetBone(ref pointBonePos, out pointBone)) { vert.Add(pointBone); } m_tmpHelperVerts.Add(vert + blockPos); } ProfilerShort.BeginNextBlock("BakeConvex"); Shapes.Add(new HkConvexVerticesShape(m_tmpHelperVerts.GetInternalArray(), m_tmpHelperVerts.Count, SHRINK_CONVEX_SHAPE, MyPerGameSettings.PhysicsConvexRadius)); ShapeInfos.Add(new ShapeInfo() { Count = 1, Min = block.Min, Max = block.Max }); ProfilerShort.End(); }
private void AddConvexShape(MySlimBlock block, bool applySkeleton) { this.m_tmpHelperVerts.Clear(); Vector3 vector = (Vector3)(block.Min * block.CubeGrid.GridSize); Vector3I vectori = (Vector3I)((block.Min * 2) + 1); MyGridSkeleton skeleton = block.CubeGrid.Skeleton; foreach (Vector3 vector3 in MyBlockVerticesCache.GetBlockVertices(block.BlockDefinition.CubeDefinition.CubeTopology, block.Orientation)) { Vector3 vector2; Vector3I pos = (Vector3I)(vectori + Vector3I.Round(vector3)); Vector3 vector4 = vector3 * block.CubeGrid.GridSizeHalf; if (applySkeleton && skeleton.TryGetBone(ref pos, out vector2)) { vector4.Add(vector2); } this.m_tmpHelperVerts.Add(vector4 + vector); } this.Shapes.Add((HkShape) new HkConvexVerticesShape(this.m_tmpHelperVerts.GetInternalArray <Vector3>(), this.m_tmpHelperVerts.Count, false, MyPerGameSettings.PhysicsConvexRadius)); ShapeInfo item = new ShapeInfo { Count = 1, Min = block.Min, Max = block.Max }; this.ShapeInfos.Add(item); }
private static MyObjectBuilder_CubeBlock ConvertDynamicGridBlockToStatic(ref MatrixD worldMatrix, MyObjectBuilder_CubeBlock origBlock) { MyDefinitionId defId = new MyDefinitionId(origBlock.TypeId, origBlock.SubtypeName); MyCubeBlockDefinition blockDefinition; MyDefinitionManager.Static.TryGetCubeBlockDefinition(defId, out blockDefinition); if (blockDefinition == null) { return(null); } var blockBuilder = Sandbox.Common.ObjectBuilders.Serializer.MyObjectBuilderSerializer.CreateNewObject(defId) as MyObjectBuilder_CubeBlock; blockBuilder.EntityId = origBlock.EntityId; // Orientation quaternion is not setup in origblock MyBlockOrientation orientation = origBlock.BlockOrientation; Quaternion rotationQuat; orientation.GetQuaternion(out rotationQuat); Matrix origRotationMatrix = Matrix.CreateFromQuaternion(rotationQuat); Matrix rotationMatrix = origRotationMatrix * worldMatrix; blockBuilder.Orientation = Quaternion.CreateFromRotationMatrix(rotationMatrix); Vector3I origSizeRotated = Vector3I.Abs(Vector3I.Round(Vector3.TransformNormal((Vector3)blockDefinition.Size, origRotationMatrix))); Vector3I origMin = origBlock.Min; Vector3I origMax = origBlock.Min + origSizeRotated - Vector3I.One; Vector3I minXForm = Vector3I.Round(Vector3.TransformNormal((Vector3)origMin, worldMatrix)); Vector3I maxXForm = Vector3I.Round(Vector3.TransformNormal((Vector3)origMax, worldMatrix)); blockBuilder.Min = Vector3I.Min(minXForm, maxXForm); return(blockBuilder); }
protected new void UpdatePastePosition() { m_pastePositionPrevious = m_pastePosition; if (MyCubeBuilder.Static.DynamicMode) { m_visible = true; IsSnapped = false; // Cast shapes commented out - difficult to place larger grids (blueprints). //Vector3D? fixedPastePosition = GetFreeSpacePlacementPositionGridAabbs(true, out m_dynamicBuildAllowed); //if (fixedPastePosition.HasValue) // m_pastePosition = fixedPastePosition.Value; //else m_pastePosition = MyCubeBuilder.IntersectionStart + m_dragDistance * MyCubeBuilder.IntersectionDirection; Matrix firstGridOrientation = GetFirstGridOrientationMatrix(); Vector3D worldRefPointOffset = Vector3.TransformNormal(m_dragPointToPositionLocal, firstGridOrientation); m_pastePosition += worldRefPointOffset; } else { m_visible = true; if (!IsSnapped) { m_pasteOrientationAngle = 0.0f; m_pasteDirForward = Vector3I.Forward; m_pasteDirUp = Vector3I.Up; } IsSnapped = true; MatrixD pasteMatrix = GetPasteMatrix(); Vector3 dragVectorGlobal = pasteMatrix.Forward * m_dragDistance; var gridSettings = m_settings.GetGridPlacementSettings(PreviewGrids[0]); if (!TrySnapToSurface(gridSettings.Mode)) { m_pastePosition = pasteMatrix.Translation + dragVectorGlobal; Matrix firstGridOrientation = GetFirstGridOrientationMatrix(); Vector3D worldRefPointOffset = Vector3.TransformNormal(m_dragPointToPositionLocal, firstGridOrientation); m_pastePosition += worldRefPointOffset; IsSnapped = true; } double gridSize = PreviewGrids[0].GridSize; if (m_settings.StaticGridAlignToCenter) { m_pastePosition = Vector3I.Round(m_pastePosition / gridSize) * gridSize; } else { m_pastePosition = Vector3I.Round(m_pastePosition / gridSize + 0.5) * gridSize - 0.5 * gridSize; } } }
// Finds the grid direction for left (x) and down (y) private void GetAxis(IMyTextPanel panel, out Vector3I xAxis, out Vector3I yAxis) { Base6Directions.Direction xAxisDir = Base6Directions.GetFlippedDirection(panel.Orientation.Left); xAxis = Vector3I.Round(Base6Directions.GetVector(xAxisDir)); Base6Directions.Direction yAxisDir = Base6Directions.GetFlippedDirection(panel.Orientation.Up); yAxis = Vector3I.Round(Base6Directions.GetVector(yAxisDir)); }
protected virtual bool TryDrillBlocks(MyCubeGrid grid, Vector3 worldPoint, bool onlyCheck, out MyStringHash blockMaterial) { var invWorld = grid.PositionComp.WorldMatrixNormalizedInv; var gridLocalPosCenter = Vector3.Transform(m_sensor.Center, invWorld); var gridLocalPos = Vector3.Transform(m_sensor.FrontPoint, invWorld); var gridLocalTarget = Vector3.Transform(worldPoint, invWorld); var gridSpacePos = Vector3I.Round(gridLocalPos / grid.GridSize); var block = grid.GetCubeBlock(gridSpacePos); if (block != null) { if (block.BlockDefinition.PhysicalMaterial.Id.SubtypeId == MyStringHash.NullOrEmpty) { blockMaterial = m_metalMaterial; } else { blockMaterial = block.BlockDefinition.PhysicalMaterial.Id.SubtypeId; } } else { blockMaterial = MyStringHash.NullOrEmpty; } int createDebris = 0; if (!onlyCheck) { if (block != null && block is IMyDestroyableObject && block.CubeGrid.BlocksDestructionEnabled) { var destroyable = (block as IMyDestroyableObject); destroyable.DoDamage(60, MyDamageType.Drill, Sync.IsServer, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0); createDebris = grid.Physics.ApplyDeformation(0.25f, 1.5f, 2f, gridLocalTarget, Vector3.Normalize(gridLocalPos - gridLocalPosCenter), MyDamageType.Drill, attackerId: m_drillEntity != null ? m_drillEntity.EntityId : 0); } } m_target = createDebris != 0 ? null : block; bool success = false; if (block != null) { if (createDebris != 0) { BoundingSphereD bsphere = m_cutOut.Sphere; BoundingBoxD aabb = BoundingBoxD.CreateFromSphere(bsphere); MyDebris.Static.CreateExplosionDebris(ref bsphere, block.CubeGrid, ref aabb, 0.3f); } success = true; } return(success); }
private void FixSnapTransformationBase6() { if (base.CopiedGrids.Count != 0) { MyCubeGrid hitEntity = base.m_hitEntity as MyCubeGrid; if (hitEntity != null) { Matrix rotationDeltaMatrixToHitGrid = this.GetRotationDeltaMatrixToHitGrid(hitEntity); foreach (MyCubeGrid local1 in base.PreviewGrids) { MatrixD worldMatrix = local1.WorldMatrix; Matrix matrix2 = (Matrix)(worldMatrix.GetOrientation() * rotationDeltaMatrixToHitGrid); MatrixD xd = MatrixD.CreateWorld(base.m_pastePosition, matrix2.Forward, matrix2.Up); local1.PositionComp.SetWorldMatrix(xd, null, false, true, true, false, false, false); } if ((hitEntity.GridSizeEnum == MyCubeSize.Large) && (base.PreviewGrids[0].GridSizeEnum == MyCubeSize.Small)) { base.m_pastePosition = hitEntity.GridIntegerToWorld(MyCubeBuilder.TransformLargeGridHitCoordToSmallGrid(base.m_hitPos, hitEntity.PositionComp.WorldMatrixNormalizedInv, hitEntity.GridSize)); } else { Vector3I vectori = Vector3I.Round(base.m_hitNormal); Vector3I gridOffset = hitEntity.WorldToGridInteger(base.m_pastePosition); Vector3I min = base.PreviewGrids[0].Min; Vector3I vectori4 = Vector3I.Abs(Vector3I.Round(Vector3D.TransformNormal(Vector3D.TransformNormal((Vector3D)((base.PreviewGrids[0].Max - min) + Vector3I.One), base.PreviewGrids[0].WorldMatrix), hitEntity.PositionComp.WorldMatrixNormalizedInv))); int num = Math.Abs(Vector3I.Dot(ref vectori, ref vectori4)); int num2 = 0; while (true) { if ((num2 >= num) || hitEntity.CanMergeCubes(base.PreviewGrids[0], gridOffset)) { if (num2 == num) { gridOffset = hitEntity.WorldToGridInteger(base.m_pastePosition); } base.m_pastePosition = hitEntity.GridIntegerToWorld(gridOffset); break; } gridOffset = (Vector3I)(gridOffset + vectori); num2++; } } for (int i = 0; i < base.PreviewGrids.Count; i++) { MyCubeGrid local2 = base.PreviewGrids[i]; MatrixD worldMatrix = local2.WorldMatrix; worldMatrix.Translation = base.m_pastePosition + Vector3.Transform(base.m_copiedGridOffsets[i], rotationDeltaMatrixToHitGrid); local2.PositionComp.SetWorldMatrix(worldMatrix, null, false, true, true, false, false, false); } if (MyDebugDrawSettings.DEBUG_DRAW_COPY_PASTE) { MyRenderProxy.DebugDrawLine3D(base.m_hitPos, base.m_hitPos + base.m_hitNormal, Color.Red, Color.Green, false, false); } } } }
private ConveyorLinePosition PositionToGridCoords(ConveyorLinePosition position) { ConveyorLinePosition position2 = new ConveyorLinePosition(); Matrix result = new Matrix(); base.Orientation.GetMatrix(out result); position2.LocalGridPosition = (Vector3I)(Vector3I.Round(Vector3.Transform(new Vector3(position.LocalGridPosition), result)) + base.Position); position2.Direction = base.Orientation.TransformDirection(position.Direction); return(position2); }
private MyNavigationTriangle AddTriangleInternal(Vector3 a, Vector3 b, Vector3 c) { int num; int num2; int num3; Vector3I pointB = Vector3I.Round(a * 256f); Vector3I pointA = Vector3I.Round(b * 256f); Vector3I vectori3 = Vector3I.Round(c * 256f); Vector3 vector = pointB / 256f; Vector3 vector2 = pointA / 256f; Vector3 vector3 = vectori3 / 256f; if (!this.m_connectionHelper.TryGetValue(new EdgeIndex(ref pointA, ref pointB), out num)) { num = -1; } if (!this.m_connectionHelper.TryGetValue(new EdgeIndex(ref vectori3, ref pointA), out num2)) { num2 = -1; } if (!this.m_connectionHelper.TryGetValue(new EdgeIndex(ref pointB, ref vectori3), out num3)) { num3 = -1; } int num4 = num2; int num5 = num3; MyNavigationTriangle triangle = base.AddTriangle(ref vector, ref vector3, ref vector2, ref num3, ref num2, ref num); if (num == -1) { this.m_connectionHelper.Add(new EdgeIndex(ref pointB, ref pointA), num); } else { this.m_connectionHelper.Remove(new EdgeIndex(ref pointA, ref pointB)); } if (num4 == -1) { this.m_connectionHelper.Add(new EdgeIndex(ref pointA, ref vectori3), num2); } else { this.m_connectionHelper.Remove(new EdgeIndex(ref vectori3, ref pointA)); } if (num5 == -1) { this.m_connectionHelper.Add(new EdgeIndex(ref vectori3, ref pointB), num3); } else { this.m_connectionHelper.Remove(new EdgeIndex(ref pointB, ref vectori3)); } return(triangle); }
public static void GetPosRoundedToGrid(ref Vector3D vecToRound, double gridSize, bool isStaticGridAlignToCenter) { if (isStaticGridAlignToCenter) { vecToRound = Vector3I.Round(vecToRound / gridSize) * gridSize; } else { vecToRound = Vector3I.Round(vecToRound / gridSize + 0.5) * gridSize - 0.5 * gridSize; } }
public void AddEdgeInfo(ref Vector3 point0, ref Vector3 point1, ref Vector3 normal0, ref Vector3 normal1, Color color, MySlimBlock owner) { Vector3 pos = (point0 + point1) * 0.5f; Vector3I edgeDirection = Vector3I.Round((point0 - point1) / this.m_gridRender.GridSize); MyCubeGridRenderCell orAddCell = this.GetOrAddCell(pos, true); if (orAddCell.AddEdgeInfo(this.CalculateEdgeHash(point0, point1), new MyEdgeInfo(ref pos, ref edgeDirection, ref normal0, ref normal1, ref color, MyStringHash.GetOrCompute(owner.BlockDefinition.EdgeType)), owner)) { this.m_dirtyCells.Add(orAddCell); } }
private void ProcessChangedGrid(MyCubeGrid newGrid) { Vector3I gridOffset = Vector3I.Round((m_grid.PositionComp.GetPosition() - newGrid.PositionComp.GetPosition()) / m_grid.GridSize); Vector3 fw = (Vector3)Vector3D.TransformNormal(m_grid.WorldMatrix.Forward, newGrid.PositionComp.WorldMatrixNormalizedInv); Vector3 up = (Vector3)Vector3D.TransformNormal(m_grid.WorldMatrix.Up, newGrid.PositionComp.WorldMatrixNormalizedInv); Base6Directions.Direction fwDir = Base6Directions.GetClosestDirection(fw); Base6Directions.Direction upDir = Base6Directions.GetClosestDirection(up); if (upDir == fwDir) { upDir = Base6Directions.GetPerpendicular(fwDir); } MatrixI transform = new MatrixI(ref gridOffset, fwDir, upDir); MyGridInfo gridInfo = new MyGridInfo(); gridInfo.Grid = newGrid; gridInfo.Transform = transform; m_splitGridInfos.Add(gridInfo); // Remove from split grid if (m_removeLocationsForGridSplits.Count > 0) { List <int> indexesToRemove = new List <int>(); for (int i = 0; i < m_removeLocationsForGridSplits.Count; ++i) { MyGeneratedBlockLocation location = m_removeLocationsForGridSplits[i]; Debug.Assert(location.GeneratedBlockType != MyStringId.NullOrEmpty); RemoveBlock(location, gridInfo, location.GeneratedBlockType); } } // Add to split grid List <MySlimBlock> newGridBlocks = new List <MySlimBlock>(); m_addLocations.RemoveWhere(delegate(MyGeneratedBlockLocation loc) { if (loc.RefBlock != null && loc.RefBlock.CubeGrid == newGrid) { newGridBlocks.Add(loc.RefBlock); return(true); } return(false); }); foreach (var newGridBlock in newGridBlocks) { Debug.Assert(newGrid == newGridBlock.CubeGrid); newGridBlock.CubeGrid.AdditionalModelGenerators.ForEach(g => g.UpdateAfterGridSpawn(newGridBlock)); } }
internal MyCubeGridRenderCell GetCell(Vector3 pos) { Vector3I cellPos = Vector3I.Round((pos - m_basePos) / (SplitCellCubeCount * m_gridRender.GridSize)); MyCubeGridRenderCell result; if (!m_cells.TryGetValue(cellPos, out result)) { result = new MyCubeGridRenderCell(m_gridRender); result.DebugName = cellPos.ToString(); m_cells[cellPos] = result; } return(result); }
private bool IsFaceTriangle(MyNavigationTriangle triangle, Vector3I cubePosition, Vector3I direction) { MyWingedEdgeMesh.FaceVertexEnumerator vertexEnumerator = triangle.GetVertexEnumerator(); vertexEnumerator.MoveNext(); vertexEnumerator.MoveNext(); vertexEnumerator.MoveNext(); cubePosition *= 0x100; Vector3I vectori4 = (Vector3I)(cubePosition + (direction * 0x80)); Vector3I vectori = Vector3I.Round(vertexEnumerator.Current * 256f) - vectori4; Vector3I vectori2 = Vector3I.Round(vertexEnumerator.Current * 256f) - vectori4; Vector3I vectori3 = Vector3I.Round(vertexEnumerator.Current * 256f) - vectori4; return(!((vectori * direction) != Vector3I.Zero) ? (!((vectori2 * direction) != Vector3I.Zero) ? (!((vectori3 * direction) != Vector3I.Zero) ? ((vectori.AbsMax() <= 0x80) && ((vectori2.AbsMax() <= 0x80) && (vectori3.AbsMax() <= 0x80))) : false) : false) : false); }
public void AddEdgeInfo(ref Vector3 point0, ref Vector3 point1, ref Vector3 normal0, ref Vector3 normal1, Color color, MySlimBlock owner) { var hash = CalculateEdgeHash(point0, point1); var pos = (point0 + point1) * 0.5f; Vector3I direction = Vector3I.Round((point0 - point1) / m_gridRender.GridSize); MyEdgeInfo info = new MyEdgeInfo(ref pos, ref direction, ref normal0, ref normal1, ref color, MyLibraryUtils.GetHash(owner.BlockDefinition.EdgeType)); var cell = GetCell(pos); if (cell.AddEdgeInfo(hash, info, owner)) { m_dirtyCells.Add(cell); } }
public static ConveyorLinePosition PositionToGridCoords(ConveyorLinePosition position, MyCubeBlock cubeBlock) { ConveyorLinePosition retval = new ConveyorLinePosition(); Matrix matrix = new Matrix(); cubeBlock.Orientation.GetMatrix(out matrix); Vector3 transformedPosition = Vector3.Transform(new Vector3(position.LocalGridPosition), matrix); retval.LocalGridPosition = Vector3I.Round(transformedPosition) + cubeBlock.Position; retval.Direction = cubeBlock.Orientation.TransformDirection(position.Direction); return(retval); }
private ConveyorLinePosition PositionToGridCoords(ConveyorLinePosition position) { ConveyorLinePosition retval = new ConveyorLinePosition(); Matrix matrix = new Matrix(); this.Orientation.GetMatrix(out matrix); Vector3 transformedPosition = Vector3.Transform(new Vector3(position.LocalGridPosition), matrix); retval.LocalGridPosition = Vector3I.Round(transformedPosition) + this.Position; retval.Direction = this.Orientation.TransformDirection(position.Direction); return(retval); }
public static bool IsAirtightBlock(IMySlimBlock block, Vector3I pos, Vector3 normal) { var def = block.BlockDefinition as MyCubeBlockDefinition; if (def == null) { return(false); } var airtight = IsAirtightFromDefinition(def, block.BuildLevelRatio); if (airtight != AirTightMode.USE_MOUNTS) { return(airtight == AirTightMode.SEALED); } Matrix matrix; block.Orientation.GetMatrix(out matrix); matrix.TransposeRotationInPlace(); Vector3 position = (block.FatBlock == null ? Vector3.Zero : (pos - block.FatBlock.Position)); Vector3I cell = Vector3I.Round(Vector3.Transform(position, matrix) + def.Center); Vector3I side = Vector3I.Round(Vector3.Transform(normal, matrix)); var pressurized = def.IsCubePressurized[cell][side]; if (pressurized == MyCubeBlockDefinition.MyCubePressurizationMark.PressurizedAlways) { return(true); } IMyDoor door = block.FatBlock as IMyDoor; if (door != null && (door.Status == DoorStatus.Closed || door.Status == DoorStatus.Closing)) { if (pressurized == MyCubeBlockDefinition.MyCubePressurizationMark.PressurizedClosed) { return(true); } else { return(IsDoorAirtightInternal(def, ref side, door.IsFullyClosed)); } } return(false); }
protected static void AddFastBuildModelWithSubparts(ref MatrixD matrix, List <MatrixD> matrices, List <string> models, MyCubeBlockDefinition blockDefinition) { if (string.IsNullOrEmpty(blockDefinition.Model)) { return; } matrices.Add(matrix); models.Add(blockDefinition.Model); var data = new MyEntitySubpart.Data(); MyCubeBlockDefinition subBlockDefinition; MatrixD subBlockMatrix; Vector3 dummyPosition; MyModel modelData = MyModels.GetModelOnlyData(blockDefinition.Model); foreach (var dummy in modelData.Dummies) { if (MyEntitySubpart.GetSubpartFromDummy(blockDefinition.Model, dummy.Key, dummy.Value, ref data)) { MatrixD mCopy = MatrixD.Multiply(data.InitialTransform, matrix); matrices.Add(mCopy); models.Add(data.File); } else if (MyFakes.ENABLE_SUBBLOCKS && MyCubeBlock.GetSubBlockDataFromDummy(blockDefinition, dummy.Key, dummy.Value, false, out subBlockDefinition, out subBlockMatrix, out dummyPosition)) { if (!string.IsNullOrEmpty(subBlockDefinition.Model)) { // Repair subblock matrix to have int axes (because preview renderer does not allow such non integer rotation). Vector3I forward = Vector3I.Round(Vector3.DominantAxisProjection(subBlockMatrix.Forward)); Vector3I invForward = Vector3I.One - Vector3I.Abs(forward); Vector3I right = Vector3I.Round(Vector3.DominantAxisProjection((Vector3)subBlockMatrix.Right * invForward)); Vector3I up; Vector3I.Cross(ref right, ref forward, out up); subBlockMatrix.Forward = forward; subBlockMatrix.Right = right; subBlockMatrix.Up = up; MatrixD mCopy = MatrixD.Multiply(subBlockMatrix, matrix); matrices.Add(mCopy); models.Add(subBlockDefinition.Model); } } } }
static MySlimBlock GetContactBlock(MyCubeGrid grid, Vector3D worldPosition, float graceDistance) { graceDistance = Math.Max(Math.Abs(graceDistance), grid.GridSize * 0.2f); graceDistance += 1f; MatrixD invWorld = grid.PositionComp.GetWorldMatrixNormalizedInv(); Vector3D localVelocity = Vector3D.TransformNormal(grid.Physics.LinearVelocity * Sandbox.Common.MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS, invWorld); Vector3D localPos; Vector3D.Transform(ref worldPosition, ref invWorld, out localPos); // MW:TODO optimize var min1 = Vector3I.Round((localPos - graceDistance - localVelocity) / grid.GridSize); var max1 = Vector3I.Round((localPos + graceDistance + localVelocity) / grid.GridSize); var min2 = Vector3I.Round((localPos + graceDistance - localVelocity) / grid.GridSize); var max2 = Vector3I.Round((localPos - graceDistance + localVelocity) / grid.GridSize); Vector3I min = Vector3I.Min(Vector3I.Min(Vector3I.Min(min1, max1), min2), max2); Vector3I max = Vector3I.Max(Vector3I.Max(Vector3I.Max(min1, max1), min2), max2); MySlimBlock resultBlock = null; float distSq = float.MaxValue; // TODO: optimize this, it should be possible using normal from contact Vector3I pos; for (pos.X = min.X; pos.X <= max.X; pos.X++) { for (pos.Y = min.Y; pos.Y <= max.Y; pos.Y++) { for (pos.Z = min.Z; pos.Z <= max.Z; pos.Z++) { var block = grid.GetCubeBlock(pos); if (block != null) { var testDistSq = (float)(pos * grid.GridSize - localPos).LengthSquared(); if (testDistSq < distSq) { distSq = testDistSq; resultBlock = block; } } } } } return(resultBlock); }
Vector3 GetPointPos(Vector3 point, MySlimBlock block, bool applySkeleton) { float gridSize = block.CubeGrid.GridSize; Vector3 pos = block.Min * gridSize; Matrix blockOrientation; block.Orientation.GetMatrix(out blockOrientation); Vector3I pointTransformed = Vector3I.Round(Vector3.Transform(point, blockOrientation)); if (applySkeleton) { pos += block.CubeGrid.Skeleton.GetBone(block.Min, pointTransformed + Vector3I.One); //pos += Vector3.Clamp(block.CubeGrid.Skeleton.Bones[boneIndex], new Vector3(-gridSize), new Vector3(gridSize)); } return(Vector3.Transform(point * gridSize / 2, blockOrientation) + pos); }
public static void RayCastGrid(this IMyCubeGrid grid, Vector3 rayStart, Vector3 direction, Action <Vector3I> visitor) { Matrix worldToLocal = Matrix.Invert(grid.WorldMatrix); direction.Normalize(); Vector3 transformedDirection = Vector3.TransformNormal(direction, worldToLocal); Vector3 currentPointF = Vector3.Transform(rayStart, worldToLocal) / grid.GridSize; Vector3I currentPoint = Vector3I.Round(currentPointF); if (!Inside(grid.Min, grid.Max, currentPoint)) { //find intersection BoundingBoxI bbI = new BoundingBoxI(grid.Min, grid.Max); var hit = bbI.Intersects(new Ray(currentPointF, transformedDirection)); if (!hit.HasValue) { //Program.instance.Log($"No misses bounding box"); return; //no intersection } currentPointF += (float)hit.Value * transformedDirection; currentPoint = Vector3I.Round(currentPointF); } //Program.instance.Log($"Starting at: {currentPoint}"); //Program.instance.Log($"Direction at: {transformedDirection}"); while (Inside(grid.Min, grid.Max, currentPoint)) { if (grid.CubeExists(currentPoint)) { visitor(currentPoint); } float toXShift = ClosestGridBlockChange(currentPointF.X, transformedDirection.X); float toYShift = ClosestGridBlockChange(currentPointF.Y, transformedDirection.Y); float toZShift = ClosestGridBlockChange(currentPointF.Z, transformedDirection.Z); currentPointF += transformedDirection * Min(toXShift, toYShift, toZShift); currentPoint = Vector3I.Round(currentPointF); //Program.instance.Log($"Shift by: {toXShift}, {toYShift}, {toZShift}"); //Program.instance.Log($"Walk:{currentPoint}"); } }
private void ProcessChangedGrid(MyCubeGrid newGrid) { Vector3I position = Vector3I.Round((this.m_grid.PositionComp.GetPosition() - newGrid.PositionComp.GetPosition()) / ((double)this.m_grid.GridSize)); Vector3 vec = (Vector3)Vector3D.TransformNormal(this.m_grid.WorldMatrix.Forward, newGrid.PositionComp.WorldMatrixNormalizedInv); Base6Directions.Direction closestDirection = Base6Directions.GetClosestDirection(vec); Base6Directions.Direction up = Base6Directions.GetClosestDirection((Vector3)Vector3D.TransformNormal(this.m_grid.WorldMatrix.Up, newGrid.PositionComp.WorldMatrixNormalizedInv)); if (up == closestDirection) { up = Base6Directions.GetPerpendicular(closestDirection); } MyGridInfo item = new MyGridInfo { Grid = newGrid, Transform = new MatrixI(ref position, closestDirection, up) }; this.m_splitGridInfos.Add(item); if (this.m_removeLocationsForGridSplits.Count > 0) { List <int> list1 = new List <int>(); for (int i = 0; i < this.m_removeLocationsForGridSplits.Count; i++) { MyGeneratedBlockLocation location = this.m_removeLocationsForGridSplits[i]; this.RemoveBlock(location, item, location.GeneratedBlockType); } } List <MySlimBlock> newGridBlocks = new List <MySlimBlock>(); this.m_addLocations.RemoveWhere(delegate(MyGeneratedBlockLocation loc) { if ((loc.RefBlock == null) || !ReferenceEquals(loc.RefBlock.CubeGrid, newGrid)) { return(false); } newGridBlocks.Add(loc.RefBlock); return(true); }); using (List <MySlimBlock> .Enumerator enumerator = newGridBlocks.GetEnumerator()) { while (enumerator.MoveNext()) { MySlimBlock newGridBlock; newGridBlock.CubeGrid.AdditionalModelGenerators.ForEach(g => g.UpdateAfterGridSpawn(newGridBlock)); } } }