public static bool TestBlockPlacementArea( MyCubeGrid targetGrid, ref MyGridPlacementSettings settings, MyBlockOrientation blockOrientation, MyCubeBlockDefinition blockDefinition, ref Vector3D translation, ref Quaternion rotation, ref Vector3 halfExtents, ref BoundingBoxD localAabb, out MyCubeGrid touchingGrid, MyEntity ignoredEntity = null, bool ignoreFracturedPieces = false) { touchingGrid = null; ProfilerShort.Begin("UseModelIntersection"); if (blockDefinition != null && blockDefinition.UseModelIntersection) { var model = VRage.Game.Models.MyModels.GetModelOnlyData(blockDefinition.Model); if (model != null) { bool newErrorFound; model.CheckLoadingErrors(blockDefinition.Context, out newErrorFound); if (newErrorFound) MyDefinitionErrors.Add(blockDefinition.Context, "There was error during loading of model, please check log file.", TErrorSeverity.Error); } if (model != null && model.HavokCollisionShapes != null) { Matrix local; blockOrientation.GetMatrix(out local); Vector3 modelOffset; Vector3.TransformNormal(ref blockDefinition.ModelOffset, ref local, out modelOffset); translation += modelOffset; int shapeCount = model.HavokCollisionShapes.Length; HkShape[] shapes = new HkShape[shapeCount]; for (int q = 0; q < shapeCount; ++q) { shapes[q] = model.HavokCollisionShapes[q]; } var shape = new HkListShape(shapes, shapeCount, HkReferencePolicy.None); Quaternion q2 = Quaternion.CreateFromForwardUp(Base6Directions.GetVector(blockOrientation.Forward), Base6Directions.GetVector(blockOrientation.Up)); rotation = rotation * q2; MyPhysics.GetPenetrationsShape(shape, ref translation, ref rotation, m_physicsBoxQueryList, MyPhysics.CollisionLayers.NoVoxelCollisionLayer); shape.Base.RemoveReference(); } else { Debug.Assert(m_physicsBoxQueryList.Count == 0, "List not cleared"); MyPhysics.GetPenetrationsBox(ref halfExtents, ref translation, ref rotation, m_physicsBoxQueryList, MyPhysics.CollisionLayers.NoVoxelCollisionLayer); } } else { Debug.Assert(m_physicsBoxQueryList.Count == 0, "List not cleared"); MyPhysics.GetPenetrationsBox(ref halfExtents, ref translation, ref rotation, m_physicsBoxQueryList, MyPhysics.CollisionLayers.NoVoxelCollisionLayer); } m_lastQueryBox.HalfExtents = halfExtents; m_lastQueryTransform = MatrixD.CreateFromQuaternion(rotation); m_lastQueryTransform.Translation = translation; var worldMatrix = targetGrid != null ? targetGrid.WorldMatrix : MatrixD.Identity; ProfilerShort.BeginNextBlock("TestPlacementAreaInternal"); bool result = TestPlacementAreaInternal(targetGrid, ref settings, blockDefinition, blockOrientation, ref localAabb, ignoredEntity, ref worldMatrix, out touchingGrid, ignoreFracturedPieces: ignoreFracturedPieces); ProfilerShort.End(); return result; }
/// <summary> /// Fills passed lists with mount point data, which is transformed using orientation /// of the block. /// </summary> /// <param name="outMountPoints">Output buffer.</param> /// <param name="performCorrection">True when you want to have correction performed for when rotation of fractional values would have different result than integers.</param> public static void TransformMountPoints(List<MyCubeBlockDefinition.MountPoint> outMountPoints, MyCubeBlockDefinition def, MyCubeBlockDefinition.MountPoint[] mountPoints, ref MyBlockOrientation orientation) { Debug.Assert(outMountPoints != null); outMountPoints.Clear(); if (mountPoints == null) return; Matrix rotation; orientation.GetMatrix(out rotation); var center = def.Center; for (int i = 0; i < mountPoints.Length; ++i) { var mountPoint = mountPoints[i]; var mp = new MyCubeBlockDefinition.MountPoint(); var centeredStart = mountPoint.Start - center; var centeredEnd = mountPoint.End - center; Vector3I.Transform(ref mountPoint.Normal, ref rotation, out mp.Normal); Vector3.Transform(ref centeredStart, ref rotation, out mp.Start); Vector3.Transform(ref centeredEnd, ref rotation, out mp.End); mp.ExclusionMask = mountPoint.ExclusionMask; mp.PropertiesMask = mountPoint.PropertiesMask; mp.Enabled = mountPoint.Enabled; // Correction of situations when 0.5 would get transformed to -0.5, resulting in different floor() (integer 0 is transformed to 0). var startICorrect = Vector3I.Floor(mountPoint.Start) - center; var endICorrect = Vector3I.Floor(mountPoint.End) - center; Vector3I.Transform(ref startICorrect, ref rotation, out startICorrect); Vector3I.Transform(ref endICorrect, ref rotation, out endICorrect); var startI = Vector3I.Floor(mp.Start); var endI = Vector3I.Floor(mp.End); var startCorrection = startICorrect - startI; var endCorrection = endICorrect - endI; mp.Start += startCorrection; mp.End += endCorrection; outMountPoints.Add(mp); } }
public static bool CanAddBlocks(MyCubeBlockDefinition definition, MyBlockOrientation orientation, MyCubeBlockDefinition otherDefinition, MyBlockOrientation otherOrientation) { Debug.Assert(MyFakes.ENABLE_COMPOUND_BLOCK_COLLISION_DUMMIES); if (!IsCompoundEnabled(definition) || !IsCompoundEnabled(otherDefinition)) return false; if (MyFakes.ENABLE_COMPOUND_BLOCK_COLLISION_DUMMIES) { Matrix thisRotation; orientation.GetMatrix(out thisRotation); m_tmpDummies.Clear(); GetCompoundCollisionDummies(definition, m_tmpDummies); Matrix otherRotation; otherOrientation.GetMatrix(out otherRotation); m_tmpOtherDummies.Clear(); GetCompoundCollisionDummies(otherDefinition, m_tmpOtherDummies); bool intersect = CompoundDummiesIntersect(ref thisRotation, ref otherRotation, m_tmpDummies, m_tmpOtherDummies); m_tmpDummies.Clear(); m_tmpOtherDummies.Clear(); return !intersect; } // Note that this part (compound templates) is not implemented, because it will not be used in future (only dummies). return true; }