private Vector3I ComputePositionInGrid(MatrixI localMatrix, MyCubeBlockDefinition blockDefinition, Vector3I min) { var center = blockDefinition.Center; var sizeMinusOne = blockDefinition.Size - 1; Vector3I rotatedBlockSize; Vector3I rotatedCenter; Vector3I.TransformNormal(ref sizeMinusOne, ref localMatrix, out rotatedBlockSize); Vector3I.TransformNormal(ref center, ref localMatrix, out rotatedCenter); var trueSize = Vector3I.Abs(rotatedBlockSize); var offsetCenter = rotatedCenter + min; if (rotatedBlockSize.X != trueSize.X) { offsetCenter.X += trueSize.X; } if (rotatedBlockSize.Y != trueSize.Y) { offsetCenter.Y += trueSize.Y; } if (rotatedBlockSize.Z != trueSize.Z) { offsetCenter.Z += trueSize.Z; } return(offsetCenter); }
private bool IsRotationValid(MyBlockOrientation refOrientation, MyBlockOrientation orientation, MyBlockOrientation[] validRotations) { Debug.Assert(validRotations != null); // Ref matrix MatrixI localMatrix = new MatrixI(Vector3I.Zero, refOrientation.Forward, refOrientation.Up); MatrixI inverseMatrix; MatrixI.Invert(ref localMatrix, out inverseMatrix); Matrix inverseMatrixF = inverseMatrix.GetFloatMatrix(); // Transform orientation to ref Base6Directions.Direction forward = Base6Directions.GetClosestDirection(Vector3.TransformNormal((Vector3)Base6Directions.GetIntVector(orientation.Forward), inverseMatrixF)); Base6Directions.Direction up = Base6Directions.GetClosestDirection(Vector3.TransformNormal((Vector3)Base6Directions.GetIntVector(orientation.Up), inverseMatrixF)); foreach (var validRotation in validRotations) { if (validRotation.Forward == forward && validRotation.Up == up) { return(true); } } return(false); }
internal override void OnTransformed(ref MatrixI transform) { foreach (KeyValuePair <ushort, MySlimBlock> pair in this.m_mapIdToBlock) { pair.Value.Transform(ref transform); } }
/// <summary> /// Registers the given room as a possibility if it isn't already registered. /// </summary> /// <param name="transform"></param> /// <param name="part"></param> private RoomMeta RegisterKey(MatrixI transform, PartFromPrefab part) { var key = new RoomKey(transform, part); RoomMeta room; if (!m_openRooms.TryGetValue(key, out room)) { var ent = new ProceduralRoom(); ent.Init(transform, part); m_openRooms[key] = room = new RoomMeta(ent); } else if (room.Nonce == m_nonce) { return(room); } room.Nonce = m_nonce; room.InFactor = 0; foreach (var mount in room.Room.MountPoints) { var other = mount.AttachedToIn(m_construction); if (other == null) { continue; } room.InFactor++; m_possibleRooms.Add(other, room); } return(room); }
private static void OnMessageCompressedRequest(ref MergingCopyPasteCompressedMsg msg, MyNetworkClient sender) { MySandboxGame.Log.WriteLine("MergingCopyPasteCompressedMsg received"); MySession.Static.SyncLayer.SendMessageToAllButOne(ref msg.CreateMessage, sender.SteamUserId); MyEntity firstEntity = OnMessageCompressedInternal(ref msg.CreateMessage); MyEntity entity; MyEntities.TryGetEntityById(msg.MergeGridId, out entity); MyCubeGrid grid = entity as MyCubeGrid; Debug.Assert(grid != null); if (grid == null) { return; } MyCubeGrid mergingGrid = firstEntity as MyCubeGrid; Debug.Assert(mergingGrid != null); if (mergingGrid == null) { return; } Vector3I offset = msg.MergeOffset; MatrixI mergeOffset = new MatrixI(ref offset, msg.MergeForward, msg.MergeUp); grid.MergeGrid_CopyPaste(mergingGrid, mergeOffset); }
internal override void OnTransformed(ref MatrixI transform) { foreach (var pair in m_blocks) { pair.Value.Transform(ref transform); } }
public static bool Intersects(ref PartFromPrefab partA, ref MatrixI transformA, ref MatrixI invTransformA, ref PartFromPrefab partB, ref MatrixI transformB, ref MatrixI invTransformB, bool testOptional, bool testQuick = false) { var cheapResult = IntersectsInternalCheap(ref partA, ref transformA, ref invTransformA, ref partB, ref transformB, ref invTransformB, testOptional); switch (cheapResult) { case CheapIntersection.Yes: return(true); case CheapIntersection.No: return(false); case CheapIntersection.Maybe: default: break; } if (testQuick) { return(true); } MatrixI abTransform; MatrixI.Multiply(ref transformA, ref invTransformB, out abTransform); var key = new IntersectKey(partA, partB, abTransform, testOptional); bool result; // ReSharper disable once ConvertIfStatementToReturnStatement // TODO when threading cause a wait when another thread is preparing this cache value? if (IntersectionCache.TryGet(key, out result)) { return(result); } return(IntersectionCache.Store(key, IntersectsInternalExpensive(ref partA, ref transformA, ref invTransformA, ref partB, ref transformB, ref invTransformB, testOptional))); }
public IntersectKey(PartFromPrefab partA, PartFromPrefab partB, MatrixI transformAB, bool testOptional) { m_partA = partA; m_partB = partB; m_transformAB = transformAB; m_testOptional = testOptional; }
/// <summary> /// Converts the given block with the given matrix for static grid. /// </summary> private static void ConvertRotatedGridBlockToStatic(ref MatrixI transform, MyObjectBuilder_CubeBlock origBlock) { MyDefinitionId defId = new MyDefinitionId(origBlock.TypeId, origBlock.SubtypeName); MyCubeBlockDefinition blockDefinition; MyDefinitionManager.Static.TryGetCubeBlockDefinition(defId, out blockDefinition); if (blockDefinition == null) { return; } // Orientation quaternion is not setup in origblock MyBlockOrientation origOrientation = origBlock.BlockOrientation; Vector3I origMin = origBlock.Min; Vector3I origMax; MySlimBlock.ComputeMax(blockDefinition, origOrientation, ref origMin, out origMax); Vector3I tMin; Vector3I tMax; Vector3I.Transform(ref origMin, ref transform, out tMin); Vector3I.Transform(ref origMax, ref transform, out tMax); Base6Directions.Direction forward = transform.GetDirection(origOrientation.Forward); Base6Directions.Direction up = transform.GetDirection(origOrientation.Up); // Write data MyBlockOrientation newBlockOrientation = new MyBlockOrientation(forward, up); Quaternion rotationQuat; newBlockOrientation.GetQuaternion(out rotationQuat); origBlock.Orientation = rotationQuat; origBlock.Min = Vector3I.Min(tMin, tMax); }
public static MatrixI Multiply(MatrixI left, MatrixI right) { MatrixI result; MatrixI.Multiply(ref left, ref right, out result); return(result); }
/// <summary> /// Transforms given compound block with matrix for static grid. Rotation of block is not changed. /// </summary> private static void ConvertRotatedGridCompoundBlockToStatic(ref MatrixI transform, MyObjectBuilder_CompoundCubeBlock origBlock) { MyDefinitionId defId = new MyDefinitionId(origBlock.TypeId, origBlock.SubtypeName); MyCubeBlockDefinition blockDefinition; MyDefinitionManager.Static.TryGetCubeBlockDefinition(defId, out blockDefinition); if (blockDefinition == null) { return; } // Orientation quaternion is not setup in origblock MyBlockOrientation origOrientation = origBlock.BlockOrientation; Vector3I origMin = origBlock.Min; Vector3I origMax; MySlimBlock.ComputeMax(blockDefinition, origOrientation, ref origMin, out origMax); Vector3I tMin; Vector3I tMax; Vector3I.Transform(ref origMin, ref transform, out tMin); Vector3I.Transform(ref origMax, ref transform, out tMax); // Write data origBlock.Min = Vector3I.Min(tMin, tMax); }
private static Vector3I ComputePositionInGrid(MatrixI localMatrix, MyCubeBlockDefinition blockDefinition, Vector3I min) { Vector3I center = blockDefinition.Center; Vector3I vector3I = blockDefinition.Size - 1; Vector3I value; Vector3I.TransformNormal(ref vector3I, ref localMatrix, out value); Vector3I a; Vector3I.TransformNormal(ref center, ref localMatrix, out a); Vector3I vector3I2 = Vector3I.Abs(value); Vector3I result = a + min; if (value.X != vector3I2.X) { result.X += vector3I2.X; } if (value.Y != vector3I2.Y) { result.Y += vector3I2.Y; } if (value.Z != vector3I2.Z) { result.Z += vector3I2.Z; } return(result); }
/// <summary> /// Converts the given grid to static with the world matrix. Instead of grid (which must have identity rotation for static grid) we transform blocks in the grid. /// </summary> /// <param name="originalGrid">grid to be transformed</param> /// <param name="worldMatrix">target world transform</param> private static void ConvertGridBuilderToStatic(MyObjectBuilder_CubeGrid originalGrid, MatrixD worldMatrix) { originalGrid.IsStatic = true; originalGrid.PositionAndOrientation = new MyPositionAndOrientation(originalGrid.PositionAndOrientation.Value.Position, Vector3.Forward, Vector3.Up); Vector3 fw = (Vector3)worldMatrix.Forward; Vector3 up = (Vector3)worldMatrix.Up; Base6Directions.Direction fwDir = Base6Directions.GetClosestDirection(fw); Base6Directions.Direction upDir = Base6Directions.GetClosestDirection(up); if (upDir == fwDir) { upDir = Base6Directions.GetPerpendicular(fwDir); } MatrixI transform = new MatrixI(Vector3I.Zero, fwDir, upDir); // Blocks in static grid - must be recreated for static grid with different orientation and position foreach (var origBlock in originalGrid.CubeBlocks) { if (origBlock is MyObjectBuilder_CompoundCubeBlock) { var origBlockCompound = origBlock as MyObjectBuilder_CompoundCubeBlock; ConvertRotatedGridCompoundBlockToStatic(ref transform, origBlockCompound); for (int i = 0; i < origBlockCompound.Blocks.Length; ++i) { var origBlockInCompound = origBlockCompound.Blocks[i]; ConvertRotatedGridBlockToStatic(ref transform, origBlockInCompound); } } else { ConvertRotatedGridBlockToStatic(ref transform, origBlock); } } }
public static BoundingBox TransformBoundingBox(BoundingBox box, ref MatrixI matrix) { Vector3 a, b; Vector3.Transform(ref box.Min, ref matrix, out a); Vector3.Transform(ref box.Max, ref matrix, out b); return(new BoundingBox(Vector3.Min(a, b), Vector3.Max(a, b))); }
private void FixCubeFace(ref Vector3I pos, ref Vector3I dir) { if (m_cubeSet.Contains(ref pos)) { // TODO: In the future, we'll have to remove the face's triangles // TODO: Cash the neighboring blocks in real-time and then perform the mesh modification on another thread var cubeBlock = m_grid.GetCubeBlock(pos); var compound = cubeBlock.FatBlock as MyCompoundCubeBlock; if (compound != null) { var blocks = compound.GetBlocks(); MySlimBlock firstBlock = null; foreach (var subblock in blocks) { if (subblock.BlockDefinition.NavigationDefinition != null) { firstBlock = subblock; break; } } if (firstBlock != null) { cubeBlock = firstBlock; } } if (cubeBlock.BlockDefinition.NavigationDefinition == null) { return; } MatrixI transform = new MatrixI(cubeBlock.Position, cubeBlock.Orientation.Forward, cubeBlock.Orientation.Up); MatrixI invTform; MatrixI.Invert(ref transform, out invTform); Vector3I meshPos; Vector3I.Transform(ref pos, ref invTform, out meshPos); Vector3I faceDir; Vector3I.TransformNormal(ref dir, ref invTform, out faceDir); var neighborMesh = cubeBlock.BlockDefinition.NavigationDefinition.Mesh; if (neighborMesh == null) { return; } List <int> list; if (neighborMesh.m_smallTriangleRegistry.TryGetValue(meshPos, out list)) { foreach (var triIndex in list) { var triangle = neighborMesh.GetTriangle(triIndex); if (IsFaceTriangle(triangle, meshPos, faceDir)) { CopyTriangle(triangle, meshPos, ref transform); } } } } }
private void ComputeMax(MyCubeBlockDefinition definition, MyBlockOrientation orientation, ref Vector3I min, out Vector3I max) { Vector3I size = definition.Size - 1; MatrixI localMatrix = new MatrixI(orientation); Vector3I.TransformNormal(ref size, ref localMatrix, out size); Vector3I.Abs(ref size, out size); max = min + size; }
private Vector3I ComputeMax(MyObjectBuilder_CubeBlock cube) { MyCubeBlockDefinition definition = MyDefinitionManager.Static.GetCubeBlockDefinition(cube.GetId()); Vector3I result = definition.Size - 1; MatrixI matrix = new MatrixI(cube.BlockOrientation); Vector3I.TransformNormal(ref result, ref matrix, out result); Vector3I.Abs(ref result, out result); return(cube.Min + result); }
public bool GetMissingBlocks(out MatrixI transform, List <int> multiBlockIndices) { for (int i = 0; i < this.MultiBlockDefinition.BlockDefinitions.Length; i++) { if (!this.Blocks.Any <MySlimBlock>(b => (b.MultiBlockIndex == i))) { multiBlockIndices.Add(i); } } return(this.GetTransform(out transform)); }
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)); } }
public static IMyTerminalBlock GetBlockFromReferenceAndPosition(IMyTerminalBlock reference, Vector3I position) { var matrix = new MatrixI(reference.Orientation); var pos = new Vector3I(-position.X, position.Y, -position.Z); Vector3I transformed; Vector3I.Transform(ref pos, ref matrix, out transformed); transformed += reference.Position; var slim = reference.CubeGrid.GetCubeBlock(transformed); return(slim == null ? null : slim.FatBlock as IMyTerminalBlock); }
public void GetTransformed(ref MatrixI tform, out Vector3 newA, out Vector3 newB, out Vector3 newC) { MyWingedEdgeMesh.FaceVertexEnumerator vertexEnumerator = this.m_navMesh.Mesh.GetFace(this.m_triIndex).GetVertexEnumerator(); vertexEnumerator.MoveNext(); newA = vertexEnumerator.Current; Vector3.Transform(ref newA, ref tform, out newA); vertexEnumerator.MoveNext(); newB = vertexEnumerator.Current; Vector3.Transform(ref newB, ref tform, out newB); vertexEnumerator.MoveNext(); newC = vertexEnumerator.Current; Vector3.Transform(ref newC, ref tform, out newC); }
public void CopyTo(MyGridSkeleton target, MatrixI transformationMatrix, MyCubeGrid targetGrid) { Vector3I oldPosition, newPosition; Vector3 oldBone, newBone; // transformationMatrix is in cube coordinates, so change it to bone coords MatrixI BoneOriginToGridOrigin = new MatrixI(new Vector3I(1, 1, 1), Base6Directions.Direction.Forward, Base6Directions.Direction.Up); MatrixI GridOriginToBoneOrigin = new MatrixI(new Vector3I(-1, -1, -1), Base6Directions.Direction.Forward, Base6Directions.Direction.Up); transformationMatrix.Translation = transformationMatrix.Translation * BoneDensity; MatrixI tmp; MatrixI.Multiply(ref GridOriginToBoneOrigin, ref transformationMatrix, out tmp); MatrixI.Multiply(ref tmp, ref BoneOriginToGridOrigin, out transformationMatrix); Matrix orientation; transformationMatrix.GetBlockOrientation().GetMatrix(out orientation); foreach (var bone in Bones) { oldPosition = bone.Key; Vector3I.Transform(ref oldPosition, ref transformationMatrix, out newPosition); Vector3 transformedBone = Vector3.Transform(bone.Value, orientation); if (target.Bones.TryGetValue(newPosition, out oldBone)) { newBone = (oldBone + transformedBone) * 0.5f; target.Bones[newPosition] = newBone; } else { target.Bones[newPosition] = transformedBone; } Vector3I cubePosition = newPosition / BoneDensity; for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { for (int k = -1; k <= 1; k++) { targetGrid.SetCubeDirty(cubePosition + new Vector3I(i, j, k)); } } } } }
public bool Intersects(PartFromPrefab other, MatrixI otherTransform, MatrixI otherITransform, bool testOptional, bool testQuick = false, ProceduralRoom ignore = null) { var bb = Utilities.TransformBoundingBox(other.BoundingBoxBoth, otherTransform); var result = false; m_roomTree.Query((x) => { var test = m_roomTree.GetUserData <ProceduralRoom>(x); var res = test != ignore && test.Intersects(other, otherTransform, otherITransform, testOptional, testQuick); result = res; return(!res); }, ref bb); return(result); }
public static void ComputeBlockMax(MyObjectBuilder_CubeBlock block, ref MyCubeBlockDefinition definition, out Vector3I max) { if (definition == null) { max = block.Min; return; } var size = definition.Size - 1; var localMatrix = new MatrixI(new MyBlockOrientation(block.BlockOrientation.Forward, block.BlockOrientation.Up)); Vector3I.TransformNormal(ref size, ref localMatrix, out size); Vector3I.Abs(ref size, out size); max = block.Min + size; }
protected static bool CheckConnectivityOnGrid(MySlimBlock block, ref MatrixI transform, ref MyGridPlacementSettings settings, MyCubeGrid hitGrid) { Vector3I position; Vector3I.Transform(ref block.Position, ref transform, out position); Vector3I forward = Base6Directions.GetIntVector(transform.GetDirection(block.Orientation.Forward)); Vector3I up = Base6Directions.GetIntVector(transform.GetDirection(block.Orientation.Up)); MyBlockOrientation blockOrientation = new MyBlockOrientation(Base6Directions.GetDirection(forward), Base6Directions.GetDirection(up)); Quaternion rotation; blockOrientation.GetQuaternion(out rotation); return(MyCubeGrid.CheckConnectivity(hitGrid, block.BlockDefinition, ref rotation, ref position)); }
private void AddBlock(MySlimBlock block) { Vector3I min = block.Min; Vector3I max = block.Max; Vector3I_RangeIterator iterator = new Vector3I_RangeIterator(ref min, ref max); while (iterator.IsValid()) { this.m_cubeSet.Add(ref min); iterator.GetNext(out min); } MatrixI transform = new MatrixI(block.Position, block.Orientation.Forward, block.Orientation.Up); this.MergeFromAnotherMesh(block.BlockDefinition.NavigationDefinition.Mesh, ref transform); }
public IEnumerable <MatrixI> GetTransform(PartMount otherMount) { HashSet <MatrixI> output; if (MountCache.TryGet(MyTuple.Create(otherMount, this), out output)) { return(output?.Select(x => { MatrixI val; MatrixI.Invert(ref x, out val); return val; })); } return(MountCache.GetOrCreate(MyTuple.Create(this, otherMount), GetTransformInternal)); }
public bool GetMissingBlocks(out MatrixI transform, List <int> multiBlockIndices) { // Fill missing indices. Debug.Assert(multiBlockIndices.Count == 0); for (int i = 0; i < MultiBlockDefinition.BlockDefinitions.Length; ++i) { if (!Blocks.Any(b => b.MultiBlockIndex == i)) { multiBlockIndices.Add(i); } } // ...and return transform return(GetTransform(out transform)); }
private void AddBlock(MySlimBlock block) { Vector3I start = block.Min; Vector3I end = block.Max; for (var it = new Vector3I.RangeIterator(ref start, ref end); it.IsValid(); it.GetNext(out start)) { Debug.Assert(!m_cubeSet.Contains(ref start)); m_cubeSet.Add(ref start); } MatrixI transform = new MatrixI(block.Position, block.Orientation.Forward, block.Orientation.Up); MergeFromAnotherMesh(block.BlockDefinition.NavigationDefinition.Mesh, ref transform); }
public void GetTransforms(PartMountPointBlock other, HashSet <MatrixI> cache) { var dirSelf = Base6Directions.GetOppositeDirection(MountDirection6); var dirOther = other.MountDirection6; if (other.BiasDirection6.HasValue && BiasDirection6.HasValue) { // Simple case. Only one possible transform. var tmp = new MatrixI(); // Mount directions need to be aligned tmp.SetDirection(dirOther, dirSelf); // Bias directions must be aligned var biasSelf = BiasDirection6.Value; var biasOther = other.BiasDirection6.Value; tmp.SetDirection(biasOther, biasSelf); // Final alignment tmp.SetDirection(Base6Directions.GetCross(dirOther, biasOther), Base6Directions.GetCross(dirSelf, biasSelf)); // Check secondary alignment when present. If it fails just return. These will never work. if (other.SecondBiasDirection6.HasValue && SecondBiasDirection6.HasValue && tmp.GetDirection(other.SecondBiasDirection6.Value) != SecondBiasDirection6.Value) { return; } tmp.Translation = AnchorLocation - Vector3I.TransformNormal(other.MountLocation, ref tmp); cache.Add(tmp); return; } // Complicated case. 4 possibilities // Perp. axis using +2 // Base direction for axis (first entry) using ~1 var dirSelfI = ((int)dirSelf & ~1) + 2; var dirOtherI = ((int)dirOther & ~1) + 2; for (var i = 0; i < 4; i++) { var tmp = new MatrixI(); tmp.SetDirection(dirOther, dirSelf); // Align one of the 4 perp. vectors with another perp vector var biasSelf = Base6Directions.EnumDirections[dirSelfI % 6]; var biasOther = Base6Directions.EnumDirections[(dirOtherI + i) % 6]; tmp.SetDirection(biasOther, biasSelf); // Complete the matrix tmp.SetDirection(Base6Directions.GetCross(dirOther, biasOther), Base6Directions.GetCross(dirSelf, biasSelf)); tmp.Translation = AnchorLocation - Vector3I.TransformNormal(other.MountLocation, ref tmp); cache.Add(tmp); } }