public static void DebugDrawOBB(MyOrientedBoundingBoxD obb, Color color, float alpha, bool depthRead, bool smooth) { MatrixD obbMatrix = MatrixD.CreateFromQuaternion(obb.Orientation); obbMatrix.Right *= obb.HalfExtent.X * 2; obbMatrix.Up *= obb.HalfExtent.Y * 2; obbMatrix.Forward *= obb.HalfExtent.Z * 2; obbMatrix.Translation = obb.Center; VRageRender.MyRenderProxy.DebugDrawOBB(obbMatrix, color, alpha, depthRead, smooth); }
public static void DebugDrawClusters() { if (Clusters == null) return; double previewScale = 2000; MatrixD previewMatrix = MatrixD.CreateWorld(DebugDrawClustersMatrix.Translation + previewScale * DebugDrawClustersMatrix.Forward, Vector3D.Forward, Vector3D.Up); m_resultWorlds.Clear(); Clusters.GetAll(m_resultWorlds); BoundingBoxD totalBox = BoundingBoxD.CreateInvalid(); foreach (var res in m_resultWorlds) { totalBox = totalBox.Include(res.AABB); } double maxAxis = totalBox.Size.AbsMax(); //double scaleAxis = 0.057142857142857141; double scaleAxis = previewScale / maxAxis; //Vector3D scale = new Vector3D(totalBox.Size.X * scaleAxis, totalBox.Size.Y * scaleAxis, totalBox.Size.Z * scaleAxis); Vector3D center = totalBox.Center; totalBox.Min -= center; totalBox.Max -= center; { BoundingBoxD scaledBox = new BoundingBoxD(totalBox.Min * scaleAxis * 1.02f, totalBox.Max * scaleAxis * 1.02f); MyOrientedBoundingBoxD oriented = new MyOrientedBoundingBoxD(scaledBox, previewMatrix); MyRenderProxy.DebugDrawOBB(oriented, Color.Green, .2f, false, false); MyRenderProxy.DebugDrawAxis(previewMatrix, 50, false); if (MySession.Static != null) { foreach (var player in Sandbox.Game.Multiplayer.Sync.Players.GetOnlinePlayers()) { if (player.Character != null) { var playerPos = Vector3D.Transform((player.Character.PositionComp.GetPosition() - center) * scaleAxis, previewMatrix); MyRenderProxy.DebugDrawSphere(playerPos, 10, Vector3.One, 1, false); } } } } Clusters.GetAllStaticObjects(m_clusterStaticObjects); foreach (var staticBB in m_clusterStaticObjects) { BoundingBoxD scaledBox = new BoundingBoxD((staticBB.Min - center) * scaleAxis, (staticBB.Max - center) * scaleAxis); MyOrientedBoundingBoxD oriented = new MyOrientedBoundingBoxD(scaledBox, previewMatrix); MyRenderProxy.DebugDrawOBB(oriented, Color.Blue, .2f, false, false); } foreach (var res in m_resultWorlds) { BoundingBoxD scaledBox = new BoundingBoxD((res.AABB.Min - center) * scaleAxis, (res.AABB.Max - center) * scaleAxis); MyOrientedBoundingBoxD oriented = new MyOrientedBoundingBoxD(scaledBox, previewMatrix); MyRenderProxy.DebugDrawOBB(oriented, Color.White, .2f, false, false); foreach (var rb in ((HkWorld)res.UserData).CharacterRigidBodies) { Vector3D rbCenter = res.AABB.Center + rb.Position; rbCenter = (rbCenter - center) * scaleAxis; rbCenter = Vector3D.Transform(rbCenter, previewMatrix); Vector3D velocity = rb.LinearVelocity; velocity = Vector3D.TransformNormal(velocity, previewMatrix) * 10; MyRenderProxy.DebugDrawLine3D(rbCenter, rbCenter + velocity, Color.Blue, Color.White, false); } foreach (var rb in ((HkWorld)res.UserData).RigidBodies) { //jn: TODO fix debug draw //MyOrientedBoundingBoxD rbbb = new MyOrientedBoundingBoxD((BoundingBoxD)rb.GetEntity().LocalAABB, rb.GetEntity().WorldMatrix); //rbbb.Center = (rbbb.Center - center) * scaleAxis; //rbbb.HalfExtent *= scaleAxis; //rbbb.Transform(previewMatrix); //MyRenderProxy.DebugDrawOBB(rbbb, Color.Yellow, 1, false, false); ////BoundingBoxD rbaa = rb.GetEntity().WorldAABB; ////rbaa.Min = (rbaa.Min - center) * scaleAxis; ////rbaa.Max = (rbaa.Max - center) * scaleAxis; ////MyRenderProxy.DebugDrawAABB(rbaa, new Vector3(0.8f, 0.8f, 0.8f), 1, 1, false); //Vector3D velocity = rb.LinearVelocity; //velocity = Vector3D.TransformNormal(velocity, previewMatrix) * 10; //MyRenderProxy.DebugDrawLine3D(rbbb.Center, rbbb.Center + velocity, Color.Red, Color.White, false); //if (velocity.Length() > 1) //{ // BoundingBoxD ideal = new BoundingBoxD(rb.GetEntity().WorldAABB.Center - MyHavokCluster.IdealClusterSize / 2, rb.GetEntity().WorldAABB.Center + MyHavokCluster.IdealClusterSize / 2); // MyOrientedBoundingBoxD idealObb = new MyOrientedBoundingBoxD(ideal, MatrixD.Identity); // idealObb.Center = (ideal.Center - center) * scaleAxis; // idealObb.HalfExtent *= scaleAxis; // idealObb.Transform(previewMatrix); // MyRenderProxy.DebugDrawOBB(idealObb, new Vector3(0, 0, 1), 1, false, false); //} } } }
/// <summary> /// Calculates amount of volume of a bounding box in voxels. /// </summary> /// <param name="localAabb">Local bounding box to query for.</param> /// <param name="worldMatrix">World matrix of the bounding box.</param> /// <returns>Pair of floats where 1st value is Volume amount and 2nd value is ratio of Volume amount to Whole volume.</returns> public MyTuple<float,float> GetVoxelContentInBoundingBox_Fast(BoundingBoxD localAabb, MatrixD worldMatrix) { MatrixD toVoxel = worldMatrix * PositionComp.WorldMatrixNormalizedInv; MatrixD toGrid; MatrixD.Invert(ref toVoxel, out toGrid); BoundingBoxD transAABB = localAabb.TransformFast(toVoxel); transAABB.Translate(SizeInMetresHalf + StorageMin); Vector3I minI = Vector3I.Floor(transAABB.Min); Vector3I maxI = Vector3I.Ceiling(transAABB.Max); double vol = localAabb.Volume / MyVoxelConstants.VOXEL_VOLUME_IN_METERS; int K = Math.Max((MathHelper.Log2Ceiling((int)vol) - MathHelper.Log2Ceiling(100)) / 3, 0); float voxelSizeAtLod = MyVoxelConstants.VOXEL_SIZE_IN_METRES * (1 << K); float voxelVolumeAtLod = voxelSizeAtLod * voxelSizeAtLod * voxelSizeAtLod; minI >>= K; maxI >>= K; // localAabb.Inflate(1 * voxelSizeAtLod); var offset = ((Size >> 1) + StorageMin) >> K; m_tempStorage.Resize(maxI - minI + 1); Storage.ReadRange(m_tempStorage, MyStorageDataTypeFlags.Content, K, minI, maxI); float resultVolume = 0; float resultPercent = 0; int hitVolumeBoxes = 0; MyOrientedBoundingBoxD worldbbox = new MyOrientedBoundingBoxD(localAabb, worldMatrix); Vector3I coord, cache; for (coord.Z = minI.Z, cache.Z = 0; coord.Z <= maxI.Z; coord.Z++, cache.Z++) { for (coord.Y = minI.Y, cache.Y = 0; coord.Y <= maxI.Y; coord.Y++, cache.Y++) { for (coord.X = minI.X, cache.X = 0; coord.X <= maxI.X; coord.X++, cache.X++) { Vector3D voxelPos = (coord - offset) * voxelSizeAtLod; Vector3D gridPoint; Vector3D.Transform(ref voxelPos, ref toGrid, out gridPoint); ContainmentType cont; //localAabb.Contains(ref gridPoint, out cont); var voxelToWorld = WorldMatrix; voxelToWorld.Translation -= (Vector3D)StorageMin + SizeInMetresHalf; BoundingBoxD voxelBox = new BoundingBoxD(); voxelBox.Min = ((Vector3D)(coord) - .5) * voxelSizeAtLod; voxelBox.Max = ((Vector3D)(coord) + .5) * voxelSizeAtLod; MyOrientedBoundingBoxD voxelBbox = new MyOrientedBoundingBoxD(voxelBox, voxelToWorld); cont = worldbbox.Contains(ref voxelBbox); if (cont == ContainmentType.Disjoint) { //VRageRender.MyRenderProxy.DebugDrawOBB( //new MyOrientedBoundingBoxD(voxelBox, voxelToWorld), Color.Red, 0.1f, //true, false); continue; } float content = m_tempStorage.Content(ref cache) / MyVoxelConstants.VOXEL_CONTENT_FULL_FLOAT; //VRageRender.MyRenderProxy.DebugDrawOBB(voxelBbox, Color.Aqua, content, // true, false); resultVolume += content * voxelVolumeAtLod; resultPercent += content; hitVolumeBoxes++; } } } resultPercent /= hitVolumeBoxes; //float localAABBVol = (float)localAabb.Volume; //if (localAABBVol < resultVolume) // resultPercent *= (float)localAabb.Volume / resultVolume; //VRageRender.MyRenderProxy.DebugDrawOBB(worldbbox, Color.Yellow, 0, // true, false); //VRageRender.MyRenderProxy.DebugWaitForFrameFinish(); return new MyTuple<float, float>(resultVolume, resultPercent); }
public override bool HandleInput() { if (base.HandleInput()) return true; bool handled = false; //foreach (var ent in MyEntities.GetEntities()) //{ // if (ent is MyCubeGrid) // { // if (ent.PositionComp.WorldAABB.Contains(MySector.MainCamera.Position) == ContainmentType.Disjoint) // { // ent.Close(); // } // } //} //var measureStart = new VRage.Library.Utils.MyTimeSpan(System.Diagnostics.Stopwatch.GetTimestamp()); var list = MyDefinitionManager.Static.GetAnimationDefinitions(); foreach (var skin in m_skins) { skin.UpdateAnimation(Vector3.Distance(MySector.MainCamera.Position,skin.PositionComp.GetPosition())); if (MyRandom.Instance.NextFloat() > 0.95f) { var randomAnim = list.ItemAt(MyRandom.Instance.Next(0, list.Count)); var command = new MyAnimationCommand() { AnimationSubtypeName = randomAnim.Id.SubtypeName, FrameOption = MyFrameOption.Loop, TimeScale = 1, BlendTime = 0.3f }; skin.AddCommand(command); } } // var measureEnd = new VRage.Library.Utils.MyTimeSpan(System.Diagnostics.Stopwatch.GetTimestamp()); // var total = measureEnd - measureStart; // m_skins.Clear(); if (m_voxelMap != null && m_voxelMap.PositionComp != null) { Vector3D center = m_voxelMap.PositionComp.WorldAABB.Center; Vector3D centerDelta = m_voxelMap.PositionComp.WorldMatrix.Translation - center; MatrixD worldMatrix = m_voxelMap.PositionComp.WorldMatrix; var rotationMatrix = Matrix.CreateRotationZ(0.01f); worldMatrix *= rotationMatrix; centerDelta = Vector3.TransformNormal(centerDelta, rotationMatrix); worldMatrix.Translation = center + centerDelta; //m_voxelMap.PositionComp.WorldMatrix = worldMatrix; SI_DYNAMICS_MULTIPLIER += 0.01f; //var tr = worldMatrix.Translation; //worldMatrix.Translation = new Vector3D(tr.X += (double)MyMath.FastSin(SI_DYNAMICS_MULTIPLIER), tr.Y, tr.Z); //worldMatrix.Translation = new Vector3D(tr.X + 100, tr.Y, tr.Z); //m_voxelMap.PositionComp.WorldMatrix = worldMatrix; var localBB = m_voxelMap.PositionComp.LocalAABB; MyOrientedBoundingBoxD orb = new MyOrientedBoundingBoxD((BoundingBoxD)localBB, m_voxelMap.PositionComp.WorldMatrix); VRageRender.MyRenderProxy.DebugDrawOBB(orb, Color.White, 0, false, false); } return handled; }
/// <summary> /// Changes the given OBB so it is Y bounded by the range where surface may exist /// </summary> private bool SetTerrainLimits(ref MyOrientedBoundingBoxD obb) { float minHeight, maxHeight; int pointCount = 4; unsafe { Vector3* points = stackalloc Vector3[4]; GetMiddleOBBLocalPoints(obb, ref points); m_planet.Provider.Shape.GetBounds(points, pointCount, out minHeight, out maxHeight); } if (minHeight.IsValid() && maxHeight.IsValid()) { Vector3 minPoint = obb.Orientation.Up * minHeight + m_planet.PositionComp.GetPosition(); Vector3 maxPoint = obb.Orientation.Up * maxHeight + m_planet.PositionComp.GetPosition(); obb.Center = (minPoint + maxPoint) * 0.5f; // maxHeight and minHeight may be the same float heightDiff = Math.Max(maxHeight - minHeight, 1); obb.HalfExtent.Y = heightDiff * 0.5f; return true; } return false; }
internal static bool BresenhamGridIntersection(MyCubeGrid grid, ref Vector3D worldStart, ref Vector3D worldEnd, out Vector3D?hitPos, MyCubeBlock weapon = null, GridAi ai = null) { var start = grid.WorldToGridInteger(worldStart); var end = grid.WorldToGridInteger(worldEnd); Vector3I delta = end - start; Vector3I step = Vector3I.Sign(delta); delta *= step; int max = delta.AbsMax(); hitPos = null; var gMinX = grid.Min.X; var gMinY = grid.Min.Y; var gMinZ = grid.Min.Z; var gMaxX = grid.Max.X; var gMaxY = grid.Max.Y; var gMaxZ = grid.Max.Z; if (ai != null) { var dir = (worldEnd - worldStart); var ray = new RayD(ref worldStart, ref dir); foreach (var sub in ai.SubGrids) { if (sub == grid) { continue; } var subDist = sub.PositionComp.WorldVolume.Intersects(ray); if (subDist.HasValue) { var rotMatrix = Quaternion.CreateFromRotationMatrix(ai.MyGrid.WorldMatrix); var obb = new MyOrientedBoundingBoxD(ai.MyGrid.PositionComp.WorldAABB.Center, ai.MyGrid.PositionComp.LocalAABB.HalfExtents, rotMatrix); Vector3D?ignoreHit; if (obb.Intersects(ref ray) != null && BresenhamGridIntersection(sub, ref worldStart, ref worldEnd, out ignoreHit, weapon)) { return(true); } } } } if (max == delta.X) { int p1 = 2 * delta.Y - delta.X; int p2 = 2 * delta.Z - delta.X; while (start.X != end.X) { start.X += step.X; if (p1 >= 0) { start.Y += step.Y; p1 -= 2 * delta.X; } if (p2 >= 0) { start.Z += step.Z; p2 -= 2 * delta.X; } p1 += 2 * delta.Y; p2 += 2 * delta.Z; var contained = gMinX <= start.X && start.X <= gMaxX && (gMinY <= start.Y && start.Y <= gMaxY) && (gMinZ <= start.Z && start.Z <= gMaxZ); if (!contained) { return(false); } MyCube cube; if (grid.TryGetCube(start, out cube) && cube.CubeBlock != weapon?.SlimBlock) { return(true); } } } else if (max == delta.Y) { int p1 = 2 * delta.X - delta.Y; int p2 = 2 * delta.Z - delta.Y; while (start.Y != end.Y) { start.Y += step.Y; if (p1 >= 0) { start.X += step.X; p1 -= 2 * delta.Y; } if (p2 >= 0) { start.Z += step.Z; p2 -= 2 * delta.Y; } p1 += 2 * delta.X; p2 += 2 * delta.Z; var contained = gMinX <= start.X && start.X <= gMaxX && (gMinY <= start.Y && start.Y <= gMaxY) && (gMinZ <= start.Z && start.Z <= gMaxZ); if (!contained) { return(false); } MyCube cube; if (grid.TryGetCube(start, out cube) && cube.CubeBlock != weapon?.SlimBlock) { return(true); } } } else { int p1 = 2 * delta.X - delta.Z; int p2 = 2 * delta.Y - delta.Z; while (start.Z != end.Z) { start.Z += step.Z; if (p1 >= 0) { start.X += step.X; p1 -= 2 * delta.Z; } if (p2 >= 0) { start.Y += step.Y; p2 -= 2 * delta.Z; } p1 += 2 * delta.X; p2 += 2 * delta.Y; var contained = gMinX <= start.X && start.X <= gMaxX && (gMinY <= start.Y && start.Y <= gMaxY) && (gMinZ <= start.Z && start.Z <= gMaxZ); if (!contained) { return(false); } MyCube cube; if (grid.TryGetCube(start, out cube) && cube.CubeBlock != weapon?.SlimBlock) { return(true); } } } return(false); }
public bool IsWeaponAreaRestricted(MyStringHash subtype, MyOrientedBoundingBoxD cubeBoundingBox, MyCubeGrid myGrid, long ignoredEntity, GridAi gridAi, out MyOrientedBoundingBoxD restrictedBox, out BoundingSphereD restrictedSphere) { _tmpNearByBlocks.Clear(); GridAi ai; if (gridAi == null) { if (!GridToMasterAi.ContainsKey(myGrid)) { restrictedSphere = new BoundingSphereD(); restrictedBox = new MyOrientedBoundingBoxD(); return(false); } ai = GridToMasterAi[myGrid]; } else { ai = gridAi; } CalculateRestrictedShapes(subtype, cubeBoundingBox, out restrictedBox, out restrictedSphere); var queryRadius = Math.Max(restrictedBox.HalfExtent.AbsMax(), restrictedSphere.Radius); if (queryRadius < 0.01) { return(false); } var restriction = WeaponAreaRestrictions[subtype]; var checkBox = restriction.RestrictionBoxInflation > 0; var checkSphere = restriction.RestrictionRadius > 0; var querySphere = new BoundingSphereD(cubeBoundingBox.Center, queryRadius); myGrid.Hierarchy.QuerySphere(ref querySphere, _tmpNearByBlocks); foreach (var grid in ai.SubGrids) { if (grid == myGrid || !GridTargetingAIs.ContainsKey(grid)) { continue; } grid.Hierarchy.QuerySphere(ref querySphere, _tmpNearByBlocks); } for (int l = 0; l < _tmpNearByBlocks.Count; l++) { var cube = _tmpNearByBlocks[l] as MyCubeBlock; if (cube == null || cube.EntityId == ignoredEntity || !WeaponCoreBlockDefs.ContainsKey(cube.BlockDefinition.Id.SubtypeId.String)) { continue; } if (!restriction.CheckForAnyWeapon && cube.BlockDefinition.Id.SubtypeId != subtype) { continue; } if (checkBox) { var cubeBox = new MyOrientedBoundingBoxD(cube.PositionComp.LocalAABB, cube.PositionComp.WorldMatrixRef); if (restrictedBox.Contains(ref cubeBox) != ContainmentType.Disjoint) { return(true); } } if (checkSphere && restrictedSphere.Contains(cube.PositionComp.WorldAABB) != ContainmentType.Disjoint) { return(true); } } return(false); }
private void AddEntities(float border, Vector3D originPosition, MyOrientedBoundingBoxD obb, List<BoundingBoxD> boundingBoxes, List<MyVoxelMap> trackedEntities) { obb.HalfExtent += new Vector3D(border, 0, border); var aabb = obb.GetAABB(); List<MyEntity> entities = new List<MyEntity>(); MyGamePruningStructure.GetAllEntitiesInBox(ref aabb, entities); //TODO: remove this? Just for Debug... if (entities.Count(e => e is MyCubeGrid) > 0) { m_lastGridsInfo.Clear(); m_lastIntersectedGridsInfoCubes.Clear(); } foreach (var entity in entities) { var grid = entity as MyCubeGrid; //TODO: let the static be here? if (grid != null && grid.IsStatic) { ProfilerShort.Begin("AddEntities.AddGridVerticesInsideOBB"); AddGridVerticesInsideOBB(grid, obb); ProfilerShort.End(); return; } var voxelMap = entity as MyVoxelMap; if (voxelMap != null) { trackedEntities.Add(voxelMap); ProfilerShort.Begin("AddEntities.AddVoxelVertices"); AddVoxelVertices(voxelMap, border, originPosition, obb, boundingBoxes); ProfilerShort.End(); return; } } }
void DrawBlockSelection(IMySlimBlock block, SelectionState state, bool primarySelection = false) { IMyCubeGrid grid = block.CubeGrid; MyCubeBlockDefinition def = (MyCubeBlockDefinition)block.BlockDefinition; Color color = (state == SelectionState.InvalidButMirrorValid ? Color.Yellow : (state == SelectionState.Valid ? Color.Green : Color.Red)); MatrixD worldMatrix; BoundingBoxD localBB; #region Compute box MyCubeBlock fatBlock = block.FatBlock as MyCubeBlock; if (fatBlock != null) { worldMatrix = fatBlock.PositionComp.WorldMatrixRef; if (Main.Tick % (Constants.TICKS_PER_SECOND / 4) == 0 || !LocalBBCache.TryGetValue(block, out localBB)) { BoundingBox localAABB = fatBlock.PositionComp.LocalAABB; localBB = new BoundingBoxD(localAABB.Min, localAABB.Max); #region Subpart localBB inclusion if (fatBlock.Subparts != null) { MatrixD transformToBlockLocal = fatBlock.PositionComp.WorldMatrixInvScaled; foreach (VRage.Game.Entity.MyEntitySubpart s1 in fatBlock.Subparts.Values) { MyOrientedBoundingBoxD obbS1 = new MyOrientedBoundingBoxD(s1.PositionComp.LocalAABB, s1.PositionComp.WorldMatrixRef); obbS1.GetCorners(Corners, 0); for (int i = 0; i < Corners.Length; i++) { Vector3D corner = Corners[i]; localBB.Include(Vector3D.Transform(corner, transformToBlockLocal)); } if (s1.Subparts != null) { foreach (VRage.Game.Entity.MyEntitySubpart s2 in s1.Subparts.Values) { MyOrientedBoundingBoxD obbS2 = new MyOrientedBoundingBoxD(s2.PositionComp.LocalAABB, s2.PositionComp.WorldMatrixRef); obbS2.GetCorners(Corners, 0); for (int i = 0; i < Corners.Length; i++) { Vector3D corner = Corners[i]; localBB.Include(Vector3D.Transform(corner, transformToBlockLocal)); } if (s2.Subparts != null) { foreach (VRage.Game.Entity.MyEntitySubpart s3 in s2.Subparts.Values) { MyOrientedBoundingBoxD obbS3 = new MyOrientedBoundingBoxD(s3.PositionComp.LocalAABB, s3.PositionComp.WorldMatrixRef); obbS3.GetCorners(Corners, 0); for (int i = 0; i < Corners.Length; i++) { Vector3D corner = Corners[i]; localBB.Include(Vector3D.Transform(corner, transformToBlockLocal)); } if (s3.Subparts != null) { foreach (VRage.Game.Entity.MyEntitySubpart s4 in s3.Subparts.Values) { MyOrientedBoundingBoxD obbS4 = new MyOrientedBoundingBoxD(s4.PositionComp.LocalAABB, s4.PositionComp.WorldMatrixRef); obbS4.GetCorners(Corners, 0); for (int i = 0; i < Corners.Length; i++) { Vector3D corner = Corners[i]; localBB.Include(Vector3D.Transform(corner, transformToBlockLocal)); } } } } } } } } } #endregion LocalBBCache[block] = localBB; } } else { Matrix localMatrix; block.Orientation.GetMatrix(out localMatrix); localMatrix.Translation = new Vector3(block.Position) * grid.GridSize; worldMatrix = localMatrix * grid.WorldMatrix; Vector3 halfSize = def.Size * (grid.GridSize * 0.5f); localBB = new BoundingBoxD(-halfSize, halfSize); } #endregion localBB.Inflate((grid.GridSizeEnum == MyCubeSize.Large ? 0.1 : 0.03)); float lineWidth; if (primarySelection) { lineWidth = (grid.GridSizeEnum == MyCubeSize.Large ? 0.02f : 0.016f); } else { lineWidth = (grid.GridSizeEnum == MyCubeSize.Large ? 0.25f : 0.1f); // thicker mirrored selections to see better in distance } DrawSelectionLines(ref worldMatrix, ref localBB, color, lineWidth); }
public void CalculateRestrictedShapes(MyStringHash subtype, MyOrientedBoundingBoxD cubeBoundingBox, out MyOrientedBoundingBoxD restrictedBox, out BoundingSphereD restrictedSphere) { restrictedSphere = new BoundingSphereD(); restrictedBox = new MyOrientedBoundingBoxD(); if (!WeaponAreaRestrictions.ContainsKey(subtype)) { return; } WeaponAreaRestriction restriction = WeaponAreaRestrictions[subtype]; if (restriction.RestrictionBoxInflation < 0.1 && restriction.RestrictionRadius < 0.1) { return; } bool checkBox = restriction.RestrictionBoxInflation > 0; bool checkSphere = restriction.RestrictionRadius > 0; if (checkBox) { restrictedBox = new MyOrientedBoundingBoxD(cubeBoundingBox.Center, cubeBoundingBox.HalfExtent, cubeBoundingBox.Orientation); restrictedBox.HalfExtent = restrictedBox.HalfExtent + new Vector3D(Math.Sign(restrictedBox.HalfExtent.X) * restriction.RestrictionBoxInflation, Math.Sign(restrictedBox.HalfExtent.Y) * restriction.RestrictionBoxInflation, Math.Sign(restrictedBox.HalfExtent.Z) * restriction.RestrictionBoxInflation); } if (checkSphere) { restrictedSphere = new BoundingSphereD(cubeBoundingBox.Center, restriction.RestrictionRadius); } }
public void CalculateLines() { DsWatch.Start("CLines"); try { if (closestPlanet != null) { var planetAtmosphereAltitude = closestPlanet.AtmosphereAltitude; var cameraUp = new Vector3D(Camera.Position - planetCentre); var cameraForward = Vector3D.CalculatePerpendicularVector(cameraUp); frustumMatrix = MatrixD.CreateWorld(Camera.Position, cameraForward, cameraUp); var offset = Vector3.Zero; var frustum = new BoundingFrustumD(Camera.ViewMatrix * customProjectionMatrix); frustumBBox = BoundingBoxD.CreateInvalid(); frustumBBox.Include(ref frustum); if (cameraAltitude < (planetAtmosphereAltitude / 2)) { var lineAmount = 100; for (int i = 0; i < lineAmount; i++) // Line calculation LOOP { lineThickness = MyUtils.GetRandomFloat(0.01f, 0.05f); offset.Y = (float)frustumBBox.Extents.Y; offset.X = MyUtils.GetRandomInt(-60, 60); offset.Z = MyUtils.GetRandomInt(-60, 60); if (offset.X >= 0 && offset.X < 1) { offset.X = offset.X + 1; } if (offset.Z >= 0 && offset.Z < 1) { offset.Z = offset.Z + 1; } Vector3D lineStartPoint = Vector3D.Transform(offset, frustumMatrix); Vector3D lineEndPoint = planetCentre; var length = frustumBBox.HalfExtents.Y * 0.25; // Shorten line length by 1/4 LineD lineCheck = new LineD(lineStartPoint, lineEndPoint, length); Vector3D finalHitPos = lineEndPoint; Vector3D hitPos = lineEndPoint; double? hitDist = double.MaxValue; double finalHitDistSq = double.MaxValue; var checkVoxel = true; var isVoxel = false; lineIntersectedGrids.Clear(); lineIntersectedVoxels.Clear(); if (frustumBBox.Intersects(ref lineCheck)) { for (int j = 0; j < rainImpactEntities.Count; j++) // Line calculation LOOP { var rainedOnEnt = rainImpactEntities[j]; var grid = rainedOnEnt as IMyCubeGrid; if (grid != null && grid.Physics != null) { lineIntersectedGrids.Add(rainedOnEnt); } else if (rainedOnEnt is MyVoxelBase) { lineIntersectedVoxels.Add(rainedOnEnt); } } for (int k = 0; k < lineIntersectedGrids.Count; k++) { var intersectedGrid = lineIntersectedGrids[k]; var cubeGrid = intersectedGrid as IMyCubeGrid; if (cubeGrid != null && cubeGrid.Physics != null) { MyOrientedBoundingBoxD gridOBB = new MyOrientedBoundingBoxD(cubeGrid.LocalAABB, cubeGrid.WorldMatrix); //DrawOBB(gridOBB, whiteColor, MySimpleObjectRasterizer.Wireframe, 0.01f); // If we don't intersect a grid continue. if (!gridOBB.Intersects(ref lineCheck).HasValue) { continue; } hitDist = GridHitCheck(cubeGrid, lineCheck, lineStartPoint, lineEndPoint); if (hitDist != null) { hitPos = lineStartPoint + (lineCheck.Direction * hitDist.Value); if (finalHitDistSq > hitDist.Value) { finalHitPos = hitPos; finalHitDistSq = hitDist.Value; checkVoxel = false; } } //LogGridBlockHits(finalHitDistSq, finalHitPos, cubeGrid, blk, lineColor); } } /* * if (checkVoxel) * { * for (int l = 0; l < lineIntersectedVoxels.Count; l++) * { * var intersectedVoxel = lineIntersectedVoxels[l]; * var voxelHitName = intersectedVoxel as MyVoxelBase; * if (voxelHitName != null) * { * var voxelCheck = VoxelHitCheck(voxelHitName, closestPlanet, lineStartPoint, lineEndPoint, lineCheck); * if (voxelCheck != Vector3D.Zero && voxelCheck != null) * { * finalHitPos = voxelCheck; * hitDist = Vector3D.Distance(lineStartPoint, finalHitPos); * //LogVoxelHits(hitDist, voxelHitName, finalHitPos, lineCheck.Length); * isVoxel = true; * } * } * } * } */ /* * // Log Loop sizes * if (_updateCount % 100 == 0) * { * Logging.Instance.WriteLine(rainImpactEntities.Count.ToString() + " " + * lineIntersectedGrids.Count.ToString() + " " + * lineIntersectedVoxels.Count.ToString()); * } */ //Logging.Instance.WriteLine(isVoxel.ToString()); float distanceTotal = 0f; var rainDropSize = MyUtils.GetRandomFloat(0.8f, 1.5f); var randSkip = MyUtils.GetRandomInt(8); var hasHit = hitDist.Value > 0.001 && (hitDist.Value < lineCheck.Length || isVoxel); var dropsInDistance = hasHit ? hitDist.Value / rainDropSize : lineCheck.Length / rainDropSize; //var nextStart = hasHit ? finalHitPos : lineStartPoint; //var dir = hasHit ? -lineCheck.Direction : lineCheck.Direction; var nextStart = hasHit ? finalHitPos : finalHitPos; var dir = hasHit ? -lineCheck.Direction : -lineCheck.Direction; //var nextStart = hasHit && !checkVoxel ? finalHitPos : finalHitPos; //var dir = hasHit && !checkVoxel ? -lineCheck.Direction : -lineCheck.Direction; lineColor = checkVoxel ? Color.Green : Color.White; if (checkVoxel && voxelHitName != null && _updateCount % 300 == 0) { //LogVoxelHits(hitDist, voxelHitName, finalHitPos, lineCheck.Length); } while (distanceTotal < dropsInDistance) { if (randSkip-- <= 0) { Droplet droplet; Droplets.AllocateOrCreate(out droplet); droplet.StartPoint = nextStart; droplet.Direction = dir; droplet.DrawLength = rainDropSize; droplet.LineColor = lineColor; randSkip = MyUtils.GetRandomInt(8); } distanceTotal += rainDropSize; nextStart += (dir * rainDropSize); } } } } } } catch (Exception e) { Logging.Instance.WriteLine(e.ToString()); } DsWatch.Complete(true); }
/// <summary> /// Handles camera collisions with environment /// </summary> /// <param name="controlledEntity"></param> /// <param name="shakeActive"></param> /// <param name="headPosition"></param> /// <param name="headDirection"></param> /// <returns>False if no correct position was found</returns> private bool HandleIntersection(MyEntity controlledEntity, MyOrientedBoundingBoxD safeOBB, bool requireRaycast, bool shakeActive, Vector3D headPosition, Vector3 headDirection) { var line = new LineD(m_target, m_position); var safeOBBLine = new LineD(line.From, line.From + line.Direction * 2 * safeOBB.HalfExtent.Length()); Vector3D castStartSafe; { MyOrientedBoundingBoxD safeObbWithCollisionExtents = new MyOrientedBoundingBoxD(safeOBB.Center, safeOBB.HalfExtent + 2 * CAMERA_RADIUS, safeOBB.Orientation); double?safeIntersection = safeObbWithCollisionExtents.Intersects(ref safeOBBLine); if (!safeIntersection.HasValue) { safeIntersection = safeOBB.HalfExtent.Length(); } double safeDistance = safeIntersection.Value; castStartSafe = line.From + line.Direction * safeDistance; } { double?unsafeIntersection = safeOBB.Intersects(ref safeOBBLine); if (!requireRaycast && unsafeIntersection.HasValue) { var castStartUnsafe = line.From + line.Direction * unsafeIntersection.Value; var castEndUnsafe = castStartSafe + line.Direction; // short raycast, not causing problems with asteroids generating geometry Physics.MyPhysics.CastRay(castStartUnsafe, castEndUnsafe, m_raycastList, MyPhysics.DefaultCollisionLayer); if (!IsRaycastOK(m_raycastList)) { return(false); } } } if (requireRaycast) { // short raycast, not causing problems with asteroids generating geometry Physics.MyPhysics.CastRay(line.From, castStartSafe + line.Direction, m_raycastList, MyPhysics.DefaultCollisionLayer); if (!IsRaycastOK(m_raycastList)) { return(false); } } HkShape shape = new HkSphereShape(CAMERA_RADIUS); try { // small shape, not causing problems with asteroids generating geometry Physics.MyPhysics.GetPenetrationsShape(shape, ref castStartSafe, ref Quaternion.Identity, m_rigidList, 15); if (m_rigidList.Count > 0) { bool sameGrid = false; if (MySession.ControlledEntity != null && m_rigidList[0].Body != null) { sameGrid = m_rigidList[0].GetCollisionEntity() == MySession.ControlledEntity; } if (sameGrid) { castStartSafe += line.Direction; } } var shapeCastLine = new LineD(castStartSafe, m_position); uint steps = 1; uint stepIdx = 0; if (shapeCastLine.Length > SHAPE_CAST_STEP) { steps = (uint)Math.Ceiling(shapeCastLine.Length / SHAPE_CAST_STEP); if (steps >= SHAPE_CAST_MAX_STEP_COUNT) { steps = SHAPE_CAST_MAX_STEP_COUNT - 1; } stepIdx = m_updateCount % steps; m_lastShapeCastDistance[stepIdx] = float.PositiveInfinity; Vector3D step = shapeCastLine.Direction * (shapeCastLine.Length / steps); shapeCastLine = new LineD(castStartSafe + stepIdx * step, castStartSafe + (stepIdx + 1) * step); } if (false) { BoundingBoxD bbox = BoundingBoxD.CreateInvalid(); bbox.Include(new BoundingSphereD(shapeCastLine.From, CAMERA_RADIUS)); bbox.Include(new BoundingSphereD(shapeCastLine.To, CAMERA_RADIUS)); VRageRender.MyRenderProxy.DebugDrawAABB(bbox, Color.Crimson, 1f, 1f, true); } var matrix = MatrixD.CreateTranslation(shapeCastLine.From); HkContactPointData?cpd; if (controlledEntity.Physics != null && controlledEntity.Physics.CharacterProxy != null) { cpd = MyPhysics.CastShapeReturnContactData(shapeCastLine.To, shape, ref matrix, controlledEntity.Physics.CharacterCollisionFilter, 0.0f); } else { cpd = MyPhysics.CastShapeReturnContactData(shapeCastLine.To, shape, ref matrix, HkGroupFilter.CalcFilterInfo(MyPhysics.DefaultCollisionLayer, 0), 0.0f); } if (cpd.HasValue) { var point = shapeCastLine.From + shapeCastLine.Direction * shapeCastLine.Length * cpd.Value.DistanceFraction; m_lastShapeCastDistance[stepIdx] = (float)(castStartSafe - point).Length(); } else { m_lastShapeCastDistance[stepIdx] = float.PositiveInfinity; } float?dist = null; for (int i = 0; i < steps; ++i) { if (m_lastShapeCastDistance[i] != float.PositiveInfinity) { dist = Math.Min(m_lastShapeCastDistance[i], dist ?? float.PositiveInfinity); } } if (dist.HasValue) { if (dist == 0.0f) { return(false); } else { m_positionSafe = castStartSafe + shapeCastLine.Direction * dist.Value; } } else { m_positionSafe = m_position; } return(true); } finally { shape.RemoveReference(); } }
public void CalculateRotationHints(MatrixD drawMatrix, BoundingBoxD worldBox, bool draw, bool fixedAxes = false, bool hideForwardAndUpArrows = false) { Matrix cameraView = MySector.MainCamera.ViewMatrix; MatrixD camWorld = MatrixD.Invert(cameraView); camWorld.Translation = drawMatrix.Translation - 6 * camWorld.Forward; cameraView = MatrixD.Invert(camWorld); m_viewProjection.View = cameraView; drawMatrix.Translation -= camWorld.Translation; m_viewProjection.CameraPosition = camWorld.Translation; camWorld.Translation = Vector3D.Zero; Matrix cameraViewAtZero = MatrixD.Transpose(camWorld); m_viewProjection.ViewAtZero = cameraViewAtZero; Vector2 screenSize = MyGuiManager.GetScreenSizeFromNormalizedSize(Vector2.One); float previewRatio = 2.75f; int hintsWidth = (int)(screenSize.X / previewRatio), hintsHeight = (int)(screenSize.Y / previewRatio), hintsXOffset = 0, hintsYOffset = 0; m_viewProjection.Viewport = new MyViewport( (int)MySector.MainCamera.Viewport.Width - hintsWidth - hintsXOffset, hintsYOffset, hintsWidth, hintsHeight); m_viewProjection.DepthRead = false; m_viewProjection.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)hintsWidth / hintsHeight, 0.1f, 10); worldBox = new BoundingBoxD(-new Vector3(MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large) * 0.5f), new Vector3(MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large)) * 0.5f); //m_rotationHintsViewProjection.Projection = MySector.MainCamera.ProjectionMatrix; int projectionId = 0; VRageRender.MyRenderProxy.AddBillboardViewProjection(projectionId, m_viewProjection); //MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, // ref worldBox, ref Vector4.One, MySimpleObjectRasterizer.Wireframe, 1, 0.04f, null, null, false, 0); if (draw) { var white = Color.White; var red = Color.Red; MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, ref worldBox, ref white, ref red, MySimpleObjectRasterizer.Solid, 1, 0.04f, "SquareFullColor", null, false, projectionId, 100); Vector2 hintText = new Vector2((int)(MySector.MainCamera.Viewport.Width - hintsWidth - hintsXOffset + hintsWidth / 2), hintsYOffset + 0.9f * hintsHeight); m_mountpointNotification.SetTextFormatArguments(MyInput.Static.GetGameControl(MyControlsSpace.CUBE_DEFAULT_MOUNTPOINT).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard)); VRageRender.MyRenderProxy.DebugDrawText2D(hintText, m_mountpointNotification.GetText(), Color.White, 1, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_TOP); } MyOrientedBoundingBoxD rotateHintsBox = new MyOrientedBoundingBoxD(Vector3D.Transform(worldBox.Center, drawMatrix), worldBox.HalfExtents, Quaternion.CreateFromRotationMatrix(drawMatrix)); //VRageRender.MyRenderProxy.DebugDrawOBB(rotateHintsBox, Vector3.One, 1, false, false); rotateHintsBox.GetCorners(m_cubeVertices, 0); //for (int vi = 0; vi < 8; vi++) //{ // VRageRender.MyRenderProxy.DebugDrawText3D(m_cubeVertices[vi], vi.ToString(), Color.White, 0.7f, false); //} //for (int vi = 0; vi < 4; vi++) //{ // VRageRender.MyRenderProxy.DebugDrawText3D((m_cubeVertices[MyOrientedBoundingBox.StartXVertices[vi]] + m_cubeVertices[MyOrientedBoundingBox.EndXVertices[vi]]) * 0.5f, vi.ToString(), Color.Red, 0.7f, false); // VRageRender.MyRenderProxy.DebugDrawText3D((m_cubeVertices[MyOrientedBoundingBox.StartYVertices[vi]] + m_cubeVertices[MyOrientedBoundingBox.EndYVertices[vi]]) * 0.5f, vi.ToString(), Color.Green, 0.7f, false); // VRageRender.MyRenderProxy.DebugDrawText3D((m_cubeVertices[MyOrientedBoundingBox.StartZVertices[vi]] + m_cubeVertices[MyOrientedBoundingBox.EndZVertices[vi]]) * 0.5f, vi.ToString(), Color.Blue, 0.7f, false); //} int closestXAxis, closestXAxis2; GetClosestCubeEdge(m_cubeVertices, Vector3D.Zero, MyOrientedBoundingBox.StartXVertices, MyOrientedBoundingBox.EndXVertices, out closestXAxis, out closestXAxis2); Vector3D startXVertex = m_cubeVertices[MyOrientedBoundingBox.StartXVertices[closestXAxis]]; Vector3D endXVertex = m_cubeVertices[MyOrientedBoundingBox.EndXVertices[closestXAxis]]; Vector3D startXVertex2 = m_cubeVertices[MyOrientedBoundingBox.StartXVertices[closestXAxis2]]; Vector3D endXVertex2 = m_cubeVertices[MyOrientedBoundingBox.EndXVertices[closestXAxis2]]; int closestYAxis, closestYAxis2; GetClosestCubeEdge(m_cubeVertices, Vector3D.Zero, MyOrientedBoundingBox.StartYVertices, MyOrientedBoundingBox.EndYVertices, out closestYAxis, out closestYAxis2); Vector3D startYVertex = m_cubeVertices[MyOrientedBoundingBox.StartYVertices[closestYAxis]]; Vector3D endYVertex = m_cubeVertices[MyOrientedBoundingBox.EndYVertices[closestYAxis]]; Vector3D startYVertex2 = m_cubeVertices[MyOrientedBoundingBox.StartYVertices[closestYAxis2]]; Vector3D endYVertex2 = m_cubeVertices[MyOrientedBoundingBox.EndYVertices[closestYAxis2]]; int closestZAxis, closestZAxis2; GetClosestCubeEdge(m_cubeVertices, Vector3D.Zero, MyOrientedBoundingBox.StartZVertices, MyOrientedBoundingBox.EndZVertices, out closestZAxis, out closestZAxis2); Vector3D startZVertex = m_cubeVertices[MyOrientedBoundingBox.StartZVertices[closestZAxis]]; Vector3D endZVertex = m_cubeVertices[MyOrientedBoundingBox.EndZVertices[closestZAxis]]; Vector3D startZVertex2 = m_cubeVertices[MyOrientedBoundingBox.StartZVertices[closestZAxis2]]; Vector3D endZVertex2 = m_cubeVertices[MyOrientedBoundingBox.EndZVertices[closestZAxis2]]; m_cubeEdges.Clear(); m_cubeEdges.Add(new BoxEdge() { Axis = 0, Edge = new LineD(startXVertex, endXVertex) }); m_cubeEdges.Add(new BoxEdge() { Axis = 1, Edge = new LineD(startYVertex, endYVertex) }); m_cubeEdges.Add(new BoxEdge() { Axis = 2, Edge = new LineD(startZVertex, endZVertex) }); if (!fixedAxes) { int rotDirection; RotationRightAxis = GetBestAxis(m_cubeEdges, MySector.MainCamera.WorldMatrix.Right, out rotDirection); RotationRightDirection = rotDirection; RotationUpAxis = GetBestAxis(m_cubeEdges, MySector.MainCamera.WorldMatrix.Up, out rotDirection); RotationUpDirection = rotDirection; RotationForwardAxis = GetBestAxis(m_cubeEdges, MySector.MainCamera.WorldMatrix.Forward, out rotDirection); RotationForwardDirection = rotDirection; } string rightControlName1 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_HORISONTAL_POSITIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard).ToString(); string rightControlName2 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_HORISONTAL_NEGATIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard).ToString(); string upControlName1 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_VERTICAL_POSITIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard).ToString(); string upControlName2 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_VERTICAL_NEGATIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard).ToString(); string forwControlName1 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_ROLL_POSITIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard).ToString(); string forwControlName2 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_ROLL_NEGATIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard).ToString(); if (MyInput.Static.IsJoystickConnected()) { rightControlName1 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_HORISONTAL_POSITIVE).ToString(); rightControlName2 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_HORISONTAL_NEGATIVE).ToString(); upControlName1 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_VERTICAL_POSITIVE).ToString(); upControlName2 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_VERTICAL_NEGATIVE).ToString(); forwControlName1 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_ROLL_POSITIVE).ToString(); forwControlName2 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_ROLL_NEGATIVE).ToString(); } Vector3D rightStart = Vector3D.Zero; Vector3D rightEnd = Vector3D.Zero; Vector3D upStart = Vector3D.Zero; Vector3D upEnd = Vector3D.Zero; Vector3D forwStart = Vector3D.Zero; Vector3D forwEnd = Vector3D.Zero; Vector3D rightStart2 = Vector3D.Zero; Vector3D rightEnd2 = Vector3D.Zero; Vector3D upStart2 = Vector3D.Zero; Vector3D upEnd2 = Vector3D.Zero; Vector3D forwStart2 = Vector3D.Zero; Vector3D forwEnd2 = Vector3D.Zero; int rightAxis = -1, upAxis = -1, forwAxis = -1; int closestRightEdge = -1, closestUpEdge = -1, closestForwEdge = -1; int closestRightEdge2 = -1, closestUpEdge2 = -1, closestForwEdge2 = -1; if (RotationRightAxis == 0) { rightStart = startXVertex; rightEnd = endXVertex; rightStart2 = startXVertex2; rightEnd2 = endXVertex2; rightAxis = 0; closestRightEdge = closestXAxis; closestRightEdge2 = closestXAxis2; } else if (RotationRightAxis == 1) { rightStart = startYVertex; rightEnd = endYVertex; rightStart2 = startYVertex2; rightEnd2 = endYVertex2; rightAxis = 1; closestRightEdge = closestYAxis; closestRightEdge2 = closestYAxis2; } else if (RotationRightAxis == 2) { rightStart = startZVertex; rightEnd = endZVertex; rightStart2 = startZVertex2; rightEnd2 = endZVertex2; rightAxis = 2; closestRightEdge = closestZAxis; closestRightEdge2 = closestZAxis2; } else { System.Diagnostics.Debug.Assert(false, "Not defined axis"); } if (RotationUpAxis == 0) { upStart = startXVertex; upEnd = endXVertex; upStart2 = startXVertex2; upEnd2 = endXVertex2; upAxis = 0; closestUpEdge = closestXAxis; closestUpEdge2 = closestXAxis2; } else if (RotationUpAxis == 1) { upStart = startYVertex; upEnd = endYVertex; upStart2 = startYVertex2; upEnd2 = endYVertex2; upAxis = 1; closestUpEdge = closestYAxis; closestUpEdge2 = closestYAxis2; } else if (RotationUpAxis == 2) { upStart = startZVertex; upEnd = endZVertex; upStart2 = startZVertex2; upEnd2 = endZVertex2; upAxis = 2; closestUpEdge = closestZAxis; closestUpEdge2 = closestZAxis2; } if (RotationForwardAxis == 0) { forwStart = startXVertex; forwEnd = endXVertex; forwStart2 = startXVertex2; forwEnd2 = endXVertex2; forwAxis = 0; closestForwEdge = closestXAxis; closestForwEdge2 = closestXAxis2; } else if (RotationForwardAxis == 1) { forwStart = startYVertex; forwEnd = endYVertex; forwStart2 = startYVertex2; forwEnd2 = endYVertex2; forwAxis = 1; closestForwEdge = closestYAxis; closestForwEdge2 = closestYAxis2; } else if (RotationForwardAxis == 2) { forwStart = startZVertex; forwEnd = endZVertex; forwStart2 = startZVertex2; forwEnd2 = endZVertex2; forwAxis = 2; closestForwEdge = closestZAxis; closestForwEdge2 = closestZAxis2; } float textScale = 0.7f; //Closest axis //VRageRender.MyRenderProxy.DebugDrawLine3D(rightStart, rightEnd, Color.Red, Color.Red, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(upStart, upEnd, Color.Green, Color.Green, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(forwStart, forwEnd, Color.Blue, Color.Blue, false); if (draw) { //if all axis are visible, all are shown on edges //if 1 axis is not visible, other 2 must be shown on faces //if 2 are not visible, they are shown on faces and the one is shown on face center //Vector3 camVector = Vector3.Normalize(rotateHintsBox.Center - MySector.MainCamera.Position); Vector3D camVector = MySector.MainCamera.ForwardVector; Vector3D rightDirection = Vector3.Normalize(rightEnd - rightStart); Vector3D upDirection = Vector3.Normalize(upEnd - upStart); Vector3D forwDirection = Vector3.Normalize(forwEnd - forwStart); float dotRight = Math.Abs(Vector3.Dot(camVector, rightDirection)); float dotUp = Math.Abs(Vector3.Dot(camVector, upDirection)); float dotForw = Math.Abs(Vector3.Dot(camVector, forwDirection)); bool drawRightOnFace = false, drawUpOnFace = false, drawForwOnFace = false; bool drawRightOnFaceCenter = false, drawUpOnFaceCenter = false, drawForwOnFaceCenter = false; float dotAngle = 0.4f; if (dotRight < dotAngle) { if (dotUp < dotAngle) { drawForwOnFaceCenter = true; drawRightOnFace = true; drawUpOnFace = true; System.Diagnostics.Debug.Assert(dotForw >= dotAngle); } else if (dotForw < dotAngle) { drawUpOnFaceCenter = true; drawRightOnFace = true; drawForwOnFace = true; System.Diagnostics.Debug.Assert(dotUp >= dotAngle); } else { drawUpOnFace = true; drawForwOnFace = true; } } else if (dotUp < dotAngle) { if (dotRight < dotAngle) { drawForwOnFaceCenter = true; drawRightOnFace = true; drawUpOnFace = true; System.Diagnostics.Debug.Assert(dotForw >= dotAngle); } else if (dotForw < dotAngle) { drawRightOnFaceCenter = true; drawUpOnFace = true; drawForwOnFace = true; System.Diagnostics.Debug.Assert(dotRight >= dotAngle); } else { drawRightOnFace = true; drawForwOnFace = true; } } else if (dotForw < dotAngle) { if (dotRight < dotAngle) { drawUpOnFaceCenter = true; drawRightOnFace = true; drawForwOnFace = true; System.Diagnostics.Debug.Assert(dotUp >= dotAngle); } else if (dotUp < dotAngle) { drawUpOnFaceCenter = true; drawRightOnFace = true; drawForwOnFace = true; System.Diagnostics.Debug.Assert(dotRight >= dotAngle); } else { drawUpOnFace = true; drawRightOnFace = true; } } //Draw according to cube visual appearance if (!(hideForwardAndUpArrows && RotationRightAxis != 1)) { if (drawRightOnFaceCenter) { // VRageRender.MyRenderProxy.DebugDrawSphere((forwStart + forwEnd + forwStart2 + forwEnd2) * 0.25f, 0.2f, Vector3.Right, 1.0f, false, false); Vector3D faceCenter = (forwStart + forwEnd + forwStart2 + forwEnd2) * 0.25f; MyTransparentGeometry.AddBillboardOriented( "ArrowLeftGreen", Vector4.One, faceCenter - RotationForwardDirection * forwDirection * 0.2f - RotationRightDirection * rightDirection * 0.01f, -RotationForwardDirection * forwDirection, -RotationUpDirection * upDirection, 0.2f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowRightGreen", Vector4.One, faceCenter + RotationForwardDirection * forwDirection * 0.2f - RotationRightDirection * rightDirection * 0.01f, RotationForwardDirection * forwDirection, RotationUpDirection * upDirection, 0.2f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(faceCenter - RotationForwardDirection * forwDirection * 0.2f - RotationRightDirection * rightDirection * 0.01f, rightControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(faceCenter + RotationForwardDirection * forwDirection * 0.2f - RotationRightDirection * rightDirection * 0.01f, rightControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } else if (drawRightOnFace) { //VRageRender.MyRenderProxy.DebugDrawLine3D(rightStart2, rightEnd2, Color.Red, Color.Red, false); Vector3 normalRightBack, normalRightForw; MyOrientedBoundingBox.GetNormalBetweenEdges(rightAxis, closestRightEdge, closestRightEdge2, out normalRightForw); Vector3D rightCenter = (rightStart + rightEnd) * 0.5f; Vector3D rightNormalForwWorld = Vector3D.TransformNormal(normalRightForw, drawMatrix); MyOrientedBoundingBox.GetNormalBetweenEdges(rightAxis, closestRightEdge2, closestRightEdge, out normalRightBack); Vector3D rightCenter2 = (rightStart2 + rightEnd2) * 0.5f; Vector3D rightNormalBackWorld = Vector3D.TransformNormal(normalRightBack, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(rightCenter, rightCenter + rightNormalForwWorld, Color.Red, Color.Red, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(rightCenter2, rightCenter2 + rightNormalBackWorld, Color.Red, Color.Red, false); int normalEdge = -1; bool opposite = false; if (closestRightEdge == 0 && closestRightEdge2 == 3) { normalEdge = closestRightEdge + 1; } else if ((closestRightEdge < closestRightEdge2) || (closestRightEdge == 3 && closestRightEdge2 == 0)) { normalEdge = closestRightEdge - 1; opposite = true; } else { normalEdge = closestRightEdge + 1; } if (RotationRightDirection < 0) { opposite = !opposite; } Vector3 rightOffset; MyOrientedBoundingBox.GetNormalBetweenEdges(rightAxis, closestRightEdge, normalEdge, out rightOffset); Vector3D rightOffsetWorld = Vector3D.TransformNormal(rightOffset, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawText3D(rightCenter + rightNormalForwWorld * 0.6f - rightOffsetWorld * 0.01f, opposite ? rightControlName2 : rightControlName1, Color.White, textScale, false); //VRageRender.MyRenderProxy.DebugDrawText3D(rightCenter2 + rightNormalBackWorld * 0.6f - rightOffsetWorld * 0.01f, opposite ? rightControlName1 : rightControlName2, Color.White, textScale, false); MyTransparentGeometry.AddBillboardOriented( "ArrowGreen", Vector4.One, rightCenter + rightNormalForwWorld * 0.4f - rightOffsetWorld * 0.01f, rightNormalBackWorld, rightDirection, 0.5f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowGreen", Vector4.One, rightCenter2 + rightNormalBackWorld * 0.4f - rightOffsetWorld * 0.01f, rightNormalForwWorld, rightDirection, 0.5f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(rightCenter + rightNormalForwWorld * 0.3f - rightOffsetWorld * 0.01f, opposite ? rightControlName1 : rightControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(rightCenter2 + rightNormalBackWorld * 0.3f - rightOffsetWorld * 0.01f, opposite ? rightControlName2 : rightControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } else //draw on edge { Vector3 normalRightBack, normalRightForw; MyOrientedBoundingBox.GetNormalBetweenEdges(rightAxis, closestRightEdge, closestRightEdge + 1, out normalRightForw); MyOrientedBoundingBox.GetNormalBetweenEdges(rightAxis, closestRightEdge, closestRightEdge - 1, out normalRightBack); Vector3D rightCenter = (rightStart + rightEnd) * 0.5f; Vector3D rightNormalForwWorld = Vector3D.TransformNormal(normalRightForw, drawMatrix); Vector3D rightNormalBackWorld = Vector3D.TransformNormal(normalRightBack, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(rightCenter, rightCenter + rightNormalForwWorld, Color.Red, Color.Red, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(rightCenter, rightCenter + rightNormalBackWorld, Color.Red, Color.Red, false); MyTransparentGeometry.AddBillboardOriented( "ArrowGreen", Vector4.One, rightCenter + rightNormalForwWorld * 0.3f - rightNormalBackWorld * 0.01f, rightNormalForwWorld, rightDirection, 0.5f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowGreen", Vector4.One, rightCenter + rightNormalBackWorld * 0.3f - rightNormalForwWorld * 0.01f, rightNormalBackWorld, rightDirection, 0.5f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(rightCenter + rightNormalForwWorld * 0.3f - rightNormalBackWorld * 0.01f, RotationRightDirection < 0 ? rightControlName1 : rightControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(rightCenter + rightNormalBackWorld * 0.3f - rightNormalForwWorld * 0.01f, RotationRightDirection < 0 ? rightControlName2 : rightControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } } if (!(hideForwardAndUpArrows && RotationUpAxis != 1)) { if (drawUpOnFaceCenter) { //VRageRender.MyRenderProxy.DebugDrawSphere((forwStart + forwEnd + forwStart2 + forwEnd2) * 0.25f, 0.2f, Vector3.Up, 1.0f, false, false); Vector3D faceCenter = (forwStart + forwEnd + forwStart2 + forwEnd2) * 0.25f; MyTransparentGeometry.AddBillboardOriented( "ArrowLeftRed", Vector4.One, faceCenter - RotationRightDirection * rightDirection * 0.2f - RotationUpDirection * upDirection * 0.01f, -RotationRightDirection * rightDirection, -RotationForwardDirection * forwDirection, 0.2f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowRightRed", Vector4.One, faceCenter + RotationRightDirection * rightDirection * 0.2f - RotationUpDirection * upDirection * 0.01f, RotationRightDirection * rightDirection, RotationForwardDirection * forwDirection, 0.2f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(faceCenter - RotationRightDirection * rightDirection * 0.2f - RotationUpDirection * upDirection * 0.01f, upControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(faceCenter + RotationRightDirection * rightDirection * 0.2f - RotationUpDirection * upDirection * 0.01f, upControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } else if (drawUpOnFace) { //VRageRender.MyRenderProxy.DebugDrawLine3D(upStart2, upEnd2, Color.Green, Color.Green, false); Vector3 normalUpBack, normalUpForw; MyOrientedBoundingBox.GetNormalBetweenEdges(upAxis, closestUpEdge, closestUpEdge2, out normalUpForw); Vector3D upCenter = (upStart + upEnd) * 0.5f; Vector3 upNormalForwWorld = Vector3.TransformNormal(normalUpForw, drawMatrix); MyOrientedBoundingBox.GetNormalBetweenEdges(upAxis, closestUpEdge2, closestUpEdge, out normalUpBack); Vector3D upCenter2 = (upStart2 + upEnd2) * 0.5f; Vector3 upNormalBackWorld = Vector3.TransformNormal(normalUpBack, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(upCenter, upCenter + upNormalForwWorld, Color.Green, Color.Green, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(upCenter2, upCenter2 + upNormalBackWorld, Color.Green, Color.Green, false); int normalEdge = -1; bool opposite = false; if (closestUpEdge == 0 && closestUpEdge2 == 3) { normalEdge = closestUpEdge + 1; } else if ((closestUpEdge < closestUpEdge2) || (closestUpEdge == 3 && closestUpEdge2 == 0)) { normalEdge = closestUpEdge - 1; opposite = true; } else { normalEdge = closestUpEdge + 1; } if (RotationUpDirection < 0) { opposite = !opposite; } Vector3 upOffset; MyOrientedBoundingBox.GetNormalBetweenEdges(upAxis, closestUpEdge, normalEdge, out upOffset); Vector3 upOffsetWorld = Vector3.TransformNormal(upOffset, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawText3D(upCenter + upNormalForwWorld * 0.6f - upOffsetWorld * 0.01f, opposite ? upControlName1 : upControlName2, Color.White, textScale, false); //VRageRender.MyRenderProxy.DebugDrawText3D(upCenter2 + upNormalBackWorld * 0.6f - upOffsetWorld * 0.01f, opposite ? upControlName2 : upControlName1, Color.White, textScale, false); MyTransparentGeometry.AddBillboardOriented( "ArrowRed", Vector4.One, upCenter + upNormalForwWorld * 0.4f - upOffsetWorld * 0.01f, upNormalBackWorld, upDirection, 0.5f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowRed", Vector4.One, upCenter2 + upNormalBackWorld * 0.4f - upOffsetWorld * 0.01f, upNormalForwWorld, upDirection, 0.5f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(upCenter + upNormalForwWorld * 0.3f - upOffsetWorld * 0.01f, opposite ? upControlName2 : upControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(upCenter2 + upNormalBackWorld * 0.3f - upOffsetWorld * 0.01f, opposite ? upControlName1 : upControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } else //draw on edge { Vector3 normalUpBack, normalUpForw; MyOrientedBoundingBox.GetNormalBetweenEdges(upAxis, closestUpEdge, closestUpEdge + 1, out normalUpForw); MyOrientedBoundingBox.GetNormalBetweenEdges(upAxis, closestUpEdge, closestUpEdge - 1, out normalUpBack); Vector3D upCenter = (upStart + upEnd) * 0.5f; Vector3 upNormalForwWorld = Vector3.TransformNormal(normalUpForw, drawMatrix); Vector3 upNormalBackWorld = Vector3.TransformNormal(normalUpBack, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(upCenter, upCenter + upNormalForwWorld, Color.Green, Color.Green, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(upCenter, upCenter + upNormalBackWorld, Color.Green, Color.Green, false); MyTransparentGeometry.AddBillboardOriented( "ArrowRed", Vector4.One, upCenter + upNormalForwWorld * 0.3f - upNormalBackWorld * 0.01f, upNormalForwWorld, upDirection, 0.5f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowRed", Vector4.One, upCenter + upNormalBackWorld * 0.3f - upNormalForwWorld * 0.01f, upNormalBackWorld, upDirection, 0.5f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(upCenter + upNormalForwWorld * 0.6f - upNormalBackWorld * 0.01f, RotationUpDirection > 0 ? upControlName1 : upControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(upCenter + upNormalBackWorld * 0.6f - upNormalForwWorld * 0.01f, RotationUpDirection > 0 ? upControlName2 : upControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } } if (!(hideForwardAndUpArrows && RotationForwardAxis != 1)) { if (drawForwOnFaceCenter) { //VRageRender.MyRenderProxy.DebugDrawSphere((rightStart + rightEnd + rightStart2 + rightEnd2) * 0.25f, 0.2f, Vector3.Backward, 1.0f, false, false); Vector3D faceCenter = (rightStart + rightEnd + rightStart2 + rightEnd2) * 0.25f; MyTransparentGeometry.AddBillboardOriented( "ArrowLeftBlue", Vector4.One, faceCenter + RotationUpDirection * upDirection * 0.2f - RotationForwardDirection * forwDirection * 0.01f, RotationUpDirection * upDirection, -RotationRightDirection * rightDirection, 0.2f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowRightBlue", Vector4.One, faceCenter - RotationUpDirection * upDirection * 0.2f - RotationForwardDirection * forwDirection * 0.01f, -RotationUpDirection * upDirection, RotationRightDirection * rightDirection, 0.2f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(faceCenter + RotationUpDirection * upDirection * 0.2f - RotationForwardDirection * forwDirection * 0.01f, forwControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(faceCenter - RotationUpDirection * upDirection * 0.2f - RotationForwardDirection * forwDirection * 0.01f, forwControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_CENTER, projectionId); } else if (drawForwOnFace) { //VRageRender.MyRenderProxy.DebugDrawLine3D(forwStart2, forwEnd2, Color.Blue, Color.Blue, false); Vector3 normalForwBack, normalForwForw; MyOrientedBoundingBox.GetNormalBetweenEdges(forwAxis, closestForwEdge, closestForwEdge2, out normalForwForw); Vector3D forwCenter = (forwStart + forwEnd) * 0.5f; Vector3 forwNormalForwWorld = Vector3.TransformNormal(normalForwForw, drawMatrix); MyOrientedBoundingBox.GetNormalBetweenEdges(forwAxis, closestForwEdge2, closestForwEdge, out normalForwBack); Vector3D forwCenter2 = (forwStart2 + forwEnd2) * 0.5f; Vector3 forwNormalBackWorld = Vector3.TransformNormal(normalForwBack, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(forwCenter, forwCenter + forwNormalForwWorld, Color.Blue, Color.Blue, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(forwCenter2, forwCenter2 + forwNormalBackWorld, Color.Blue, Color.Blue, false); int normalEdge = -1; bool opposite = false; if (closestForwEdge == 0 && closestForwEdge2 == 3) { normalEdge = closestForwEdge + 1; } else if ((closestForwEdge < closestForwEdge2) || (closestForwEdge == 3 && closestForwEdge2 == 0)) { normalEdge = closestForwEdge - 1; opposite = true; } else { normalEdge = closestForwEdge + 1; } if (RotationForwardDirection < 0) { opposite = !opposite; } Vector3 forwOffset; MyOrientedBoundingBox.GetNormalBetweenEdges(forwAxis, closestForwEdge, normalEdge, out forwOffset); Vector3 forwOffsetWorld = Vector3.TransformNormal(forwOffset, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawText3D(forwCenter + forwNormalForwWorld * 0.6f - forwOffsetWorld * 0.01f, opposite ? forwControlName2 : forwControlName1, Color.White, textScale, false); //VRageRender.MyRenderProxy.DebugDrawText3D(forwCenter2 + forwNormalBackWorld * 0.6f - forwOffsetWorld * 0.01f, opposite ? forwControlName1 : forwControlName2, Color.White, textScale, false); MyTransparentGeometry.AddBillboardOriented( "ArrowBlue", Vector4.One, forwCenter + forwNormalForwWorld * 0.4f - forwOffsetWorld * 0.01f, forwNormalBackWorld, forwDirection, 0.5f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowBlue", Vector4.One, forwCenter2 + forwNormalBackWorld * 0.4f - forwOffsetWorld * 0.01f, forwNormalForwWorld, forwDirection, 0.5f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(forwCenter + forwNormalForwWorld * 0.3f - forwOffsetWorld * 0.01f, opposite ? forwControlName1 : forwControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(forwCenter2 + forwNormalBackWorld * 0.3f - forwOffsetWorld * 0.01f, opposite ? forwControlName2 : forwControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } else //draw on edge { Vector3 normalForwBack, normalForwForw; MyOrientedBoundingBox.GetNormalBetweenEdges(forwAxis, closestForwEdge, closestForwEdge + 1, out normalForwForw); MyOrientedBoundingBox.GetNormalBetweenEdges(forwAxis, closestForwEdge, closestForwEdge - 1, out normalForwBack); Vector3D forwCenter = (forwStart + forwEnd) * 0.5f; Vector3 forwNormalForwWorld = Vector3.TransformNormal(normalForwForw, drawMatrix); Vector3 forwNormalBackWorld = Vector3.TransformNormal(normalForwBack, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(forwCenter, forwCenter + forwNormalForwWorld, Color.Blue, Color.Blue, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(forwCenter, forwCenter + forwNormalBackWorld, Color.Blue, Color.Blue, false); MyTransparentGeometry.AddBillboardOriented( "ArrowBlue", Vector4.One, forwCenter + forwNormalForwWorld * 0.3f - forwNormalBackWorld * 0.01f, forwNormalForwWorld, forwDirection, 0.5f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowBlue", Vector4.One, forwCenter + forwNormalBackWorld * 0.3f - forwNormalForwWorld * 0.01f, forwNormalBackWorld, forwDirection, 0.5f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(forwCenter + forwNormalForwWorld * 0.3f - forwNormalBackWorld * 0.01f, RotationForwardDirection < 0 ? forwControlName1 : forwControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(forwCenter + forwNormalBackWorld * 0.3f - forwNormalForwWorld * 0.01f, RotationForwardDirection < 0 ? forwControlName2 : forwControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } } } }
public bool IsCameraPositionOk(Matrix worldMatrix) { IMyCameraController cameraController = MySession.Static.CameraController; if (cameraController == null) return true; MyEntity topControlledEntity = ((MyEntity)cameraController).GetTopMostParent(); if (topControlledEntity.Closed) return false; var localAABBHr = topControlledEntity.PositionComp.LocalAABBHr; Vector3D center = Vector3D.Transform((Vector3D)localAABBHr.Center, worldMatrix); var safeOBB = new MyOrientedBoundingBoxD(center, localAABBHr.HalfExtents, Quaternion.CreateFromRotationMatrix(worldMatrix.GetOrientation())); //VRageRender.MyRenderProxy.DebugDrawOBB(safeOBB, Vector3.One, 1, false, false); //VRageRender.MyRenderProxy.DebugDrawAxis(topControlledEntity.WorldMatrix, 2, false); bool camPosIsOk = HandleIntersection(topControlledEntity, safeOBB, topControlledEntity is Sandbox.Game.Entities.Character.MyCharacter, true, m_target, m_targetOrientation.Forward); return camPosIsOk; }
public override void Draw() { base.Draw(); if (m_showVoxelProbe) { float halfSize = m_probeSize * .5f; float lodSize = 1 << m_probeLod; if (m_moveProbe) { m_probePosition = MySector.MainCamera.Position + MySector.MainCamera.ForwardVector * m_probeSize * 3; } BoundingBox bb; BoundingBoxD bbp; // Box used for drawing and finding the probe and drawing bb = new BoundingBox(m_probePosition - halfSize, m_probePosition + halfSize); bbp = (BoundingBoxD)bb; m_voxels.Clear(); MyGamePruningStructure.GetAllVoxelMapsInBox(ref bbp, m_voxels); MyVoxelBase map = null; double distance = double.PositiveInfinity; foreach (var vox in m_voxels) { var d = Vector3D.Distance(vox.WorldMatrix.Translation, m_probePosition); if (d < distance) { distance = d; map = vox; } } ContainmentType cont = ContainmentType.Disjoint; if (map != null) { if (map is MyVoxelPhysics) { map = ((MyVoxelPhysics)map).Parent; } Vector3 localPos = Vector3.Transform(m_probePosition, map.PositionComp.WorldMatrixInvScaled); localPos += map.SizeInMetresHalf; // Create similar bounding box in storage space bb = new BoundingBox(localPos - halfSize, localPos + halfSize); m_probedVoxel = map; Section("Probing {1}: {0}", map.StorageName, map.GetType().Name); Text("Probe mode: {0}", m_mode); if (m_mode == ProbeMode.Intersect) { Text("Local Pos: {0}", localPos); Text("Probe Size: {0}", m_probeSize); cont = map.Storage.Intersect(ref bb, false); Text("Result: {0}", cont.ToString()); bbp = (BoundingBoxD)bb; } else { Vector3I min = Vector3I.Floor(bb.Min / lodSize + .5f); Vector3I max = min + ((int)m_probeSize >> m_probeLod) - 1; bbp = new BoundingBoxD(min << m_probeLod, (max + 1) << m_probeLod); Text("Probe Size: {0}({1})", (max - min).X + 1, m_probeSize); Text("Probe LOD: {0}", m_probeLod); var requestData = (MyStorageDataTypeEnum)(int)m_mode; MyVoxelRequestFlags flags = MyVoxelRequestFlags.ContentChecked; m_target.Resize(max - min + 1); m_target.Clear(MyStorageDataTypeEnum.Content, 0); m_target.Clear(MyStorageDataTypeEnum.Material, 0); map.Storage.ReadRange(m_target, (MyStorageDataTypeFlags)(1 << (int)requestData), m_probeLod, ref min, ref max, ref flags); if (requestData == MyStorageDataTypeEnum.Content) { if (flags.HasFlag(MyVoxelRequestFlags.EmptyContent)) { cont = ContainmentType.Disjoint; } else if (flags.HasFlag(MyVoxelRequestFlags.FullContent)) { cont = ContainmentType.Contains; } else { int val = m_target.ValueWhenAllEqual(requestData); if (val == -1) { cont = ContainmentType.Intersects; } else if (val >= MyVoxelConstants.VOXEL_ISO_LEVEL) { cont = ContainmentType.Contains; } else { cont = ContainmentType.Disjoint; } } DrawContentsInfo(m_target); } else { cont = ContainmentType.Disjoint; DrawMaterialsInfo(m_target); } Text(Color.Yellow, 1.5f, "Voxel Editing:"); Text("Value to set (Ctrl+Mousewheel): {0}", m_valueToSet); if (m_probeLod != 0) { Text(Color.Red, "Writing to storage is only possible when probe is set to LOD 0"); } else { Text("Use primary mouse button to set."); Text("Position/Extents: {0}/{1}", bbp.Min, bbp.Extents); if (MyInput.Static.IsLeftMousePressed()) { if (requestData == MyStorageDataTypeEnum.Content) { m_target.BlockFillContent(Vector3I.Zero, m_target.Size3D - Vector3I.One, m_valueToSet); } else { m_target.BlockFillMaterial(Vector3I.Zero, m_target.Size3D - Vector3I.One, m_valueToSet); } map.Storage.WriteRange(m_target, (MyStorageDataTypeFlags)(1 << (int)requestData), ref min, ref max); } } } } else { Section("No Voxel Found"); Text("Probe mode: {0}", m_mode); Text("Probe Size: {0}", m_probeSize); } Color c = ColorForContainment(cont); if (map != null) { bbp = bbp.Translate(-map.SizeInMetresHalf); MyOrientedBoundingBoxD oobb = new MyOrientedBoundingBoxD(bbp, map.WorldMatrix); MyRenderProxy.DebugDrawOBB(oobb, c, 0.5f, true, false); } else { MyRenderProxy.DebugDrawAABB(bbp, c, 0.5f, 1.0f, true); } } }
public override void DebugDraw() { if (MyDebugDrawSettings.DEBUG_DRAW_FIXED_BLOCK_QUERIES) { foreach (var b in m_cubeGrid.GetBlocks()) { var geometryBox = b.FatBlock.GetGeometryLocalBox(); //geometryBox.Inflate(0.5f); Vector3 halfExtents = geometryBox.Size / 2; Vector3D pos; b.ComputeScaledCenter(out pos); pos += geometryBox.Center; pos = Vector3D.Transform(pos, m_cubeGrid.WorldMatrix); Matrix blockMatrix; b.Orientation.GetMatrix(out blockMatrix); var q = Quaternion.CreateFromRotationMatrix(blockMatrix * m_cubeGrid.WorldMatrix.GetOrientation()); Sandbox.Engine.Physics.MyPhysics.GetPenetrationsBox(ref halfExtents, ref pos, ref q, m_penetrations, Sandbox.Engine.Physics.MyPhysics.CollisionLayers.CollideWithStaticLayer); bool isStatic = false; foreach (var p in m_penetrations) { var e = p.GetCollisionEntity(); if (e != null && e is MyVoxelMap) { isStatic = true; break; } } m_penetrations.Clear(); MyOrientedBoundingBoxD obb = new MyOrientedBoundingBoxD(pos, halfExtents, q); MyRenderProxy.DebugDrawOBB(obb, isStatic ? Color.Green : Color.Red, 0.1f, false, false); } } if (MyDebugDrawSettings.DEBUG_DRAW_GRID_NAMES || MyDebugDrawSettings.DEBUG_DRAW_GRID_CONTROL) { string text = ""; var color = Color.White; if (MyDebugDrawSettings.DEBUG_DRAW_GRID_NAMES) text += m_cubeGrid.ToString() + " "; if (MyDebugDrawSettings.DEBUG_DRAW_GRID_CONTROL) { var controllingPlayer = Sync.Players.GetControllingPlayer(m_cubeGrid); if (controllingPlayer != null) { text += "Controlled by: " + controllingPlayer.DisplayName; color = Color.LightGreen; } } MyRenderProxy.DebugDrawText3D(m_cubeGrid.PositionComp.WorldAABB.Center, text, color, 0.7f, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); } MyRenderComponentCubeGrid gridRender = m_cubeGrid.Render; if (MyDebugDrawSettings.DEBUG_DRAW_BLOCK_GROUPS) { var tpos = m_cubeGrid.PositionComp.WorldMatrix.Translation; foreach (var group in m_cubeGrid.BlockGroups) { MyRenderProxy.DebugDrawText3D(tpos, group.Name.ToString(), Color.Red, 1, false); tpos += m_cubeGrid.PositionComp.WorldMatrix.Right * group.Name.Length * 0.1f; } } if (MyDebugDrawSettings.DEBUG_DRAW_GRID_DIRTY_BLOCKS) { foreach (var b in m_dirtyBlocks) { var color = m_cubeGrid.GetCubeBlock(b.Key) != null ? Color.Red.ToVector3() : Color.Yellow.ToVector3(); var m = Matrix.CreateScale(m_cubeGrid.GridSize) * Matrix.CreateTranslation(b.Key * m_cubeGrid.GridSize) * m_cubeGrid.WorldMatrix; MyRenderProxy.DebugDrawOBB(m, color, 0.15f, false, true); } } // Bone debug draw if (MyDebugDrawSettings.DEBUG_DRAW_DISPLACED_BONES) { Vector3 cameraPos = (Vector3)MySector.MainCamera.Position; foreach (var bone in m_cubeGrid.Skeleton.Bones) { var bonePos = (bone.Key / (float)m_cubeGrid.Skeleton.BoneDensity) * gridRender.GridSize + bone.Value; bonePos -= new Vector3(gridRender.GridSize / m_cubeGrid.Skeleton.BoneDensity); Vector3 pos = Vector3.Transform(bonePos, (Matrix)m_cubeGrid.PositionComp.WorldMatrix); MyRenderProxy.DebugDrawSphere(pos, 0.05f, Color.Red.ToVector3(), 0.5f, false, true); if ((cameraPos - pos).LengthSquared() < 200.0f) MyRenderProxy.DebugDrawText3D(pos, bone.Key.ToString(), Color.Red, 0.4f, false); } } if (MyDebugDrawSettings.DEBUG_DRAW_STRUCTURAL_INTEGRITY && m_cubeGrid.StructuralIntegrity != null) { m_cubeGrid.StructuralIntegrity.DebugDraw(); } if (MyDebugDrawSettings.DEBUG_DRAW_CUBES) { foreach (var cubeBlock in m_cubeGrid.CubeBlocks) { var cb = cubeBlock.FatBlock; if (cb == null) continue; cb.DebugDraw(); } } m_cubeGrid.GridSystems.DebugDraw(); if (MyDebugDrawSettings.DEBUG_DRAW_GRID_TERMINAL_SYSTEMS) { /* if (grid.OnBlockAdded != null) { MyRenderProxy.DebugDrawText3D(Entity.PositionComp.WorldMatrix.Translation + new Vector3(0.0f, 0.0f, 0.5f), grid.OnBlockAdded.GetInvocationList().Count().ToString(), Color.NavajoWhite, 1.0f, false); }*/ } if (MyFakes.ENABLE_TRASH_REMOVAL && MyDebugDrawSettings.DEBUG_DRAW_TRASH_REMOVAL) { bool isTrash = m_cubeGrid.IsTrash(); Color color = isTrash ? Color.Red : Color.Green; float sphereRadius = m_cubeGrid.PositionComp.LocalAABB.HalfExtents.AbsMax(); Vector3D com = m_cubeGrid.Physics != null ? m_cubeGrid.Physics.CenterOfMassWorld : m_cubeGrid.PositionComp.WorldMatrix.Translation; MyRenderProxy.DebugDrawSphere(com, sphereRadius, color, 1.0f, false); } if (MyDebugDrawSettings.DEBUG_DRAW_GRID_ORIGINS) { MyRenderProxy.DebugDrawAxis(m_cubeGrid.PositionComp.WorldMatrix, 1.0f, false); } if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS_ALL) { foreach (MySlimBlock block in m_cubeGrid.GetBlocks()) { if((m_cubeGrid.GridIntegerToWorld(block.Position) - MySector.MainCamera.Position).LengthSquared() < 200) DebugDrawMountPoints(block); } } if(MyDebugDrawSettings.DEBUG_DRAW_BLOCK_INTEGRITY) { if (MySector.MainCamera != null && (MySector.MainCamera.Position - m_cubeGrid.PositionComp.WorldVolume.Center).Length() < 16 +m_cubeGrid.PositionComp.WorldVolume.Radius) foreach (var cubeBlock in m_cubeGrid.CubeBlocks) { var pos = m_cubeGrid.GridIntegerToWorld(cubeBlock.Position); if (m_cubeGrid.GridSizeEnum == MyCubeSize.Large || (MySector.MainCamera != null && (MySector.MainCamera.Position - pos).LengthSquared() < 9)) { float integrity = 0; if (cubeBlock.FatBlock is MyCompoundCubeBlock) { foreach (var b in (cubeBlock.FatBlock as MyCompoundCubeBlock).GetBlocks()) integrity += b.Integrity * b.BlockDefinition.MaxIntegrityRatio; } else integrity = cubeBlock.Integrity * cubeBlock.BlockDefinition.MaxIntegrityRatio; MyRenderProxy.DebugDrawText3D(m_cubeGrid.GridIntegerToWorld(cubeBlock.Position), ((int)integrity).ToString(), Color.White, m_cubeGrid.GridSizeEnum == MyCubeSize.Large ? 0.65f : 0.5f, false); } } } base.DebugDraw(); }
public override void DebugDraw() { if (MyDebugDrawSettings.DEBUG_DRAW_FIXED_BLOCK_QUERIES) { foreach (var b in m_cubeGrid.GetBlocks()) { var geometryBox = b.FatBlock.GetGeometryLocalBox(); //geometryBox.Inflate(0.5f); Vector3 halfExtents = geometryBox.Size / 2; Vector3D pos; b.ComputeScaledCenter(out pos); pos += geometryBox.Center; pos = Vector3D.Transform(pos, m_cubeGrid.WorldMatrix); Matrix blockMatrix; b.Orientation.GetMatrix(out blockMatrix); var q = Quaternion.CreateFromRotationMatrix(blockMatrix * m_cubeGrid.WorldMatrix.GetOrientation()); Sandbox.Engine.Physics.MyPhysics.GetPenetrationsBox(ref halfExtents, ref pos, ref q, m_penetrations, Sandbox.Engine.Physics.MyPhysics.CollisionLayers.CollideWithStaticLayer); bool isStatic = false; foreach (var p in m_penetrations) { var e = p.GetCollisionEntity(); if (e != null && e is MyVoxelMap) { isStatic = true; break; } } m_penetrations.Clear(); MyOrientedBoundingBoxD obb = new MyOrientedBoundingBoxD(pos, halfExtents, q); MyRenderProxy.DebugDrawOBB(obb, isStatic ? Color.Green : Color.Red, 0.1f, false, false); } } if (MyDebugDrawSettings.DEBUG_DRAW_GRID_NAMES || MyDebugDrawSettings.DEBUG_DRAW_GRID_CONTROL) { string text = ""; var color = Color.White; if (MyDebugDrawSettings.DEBUG_DRAW_GRID_NAMES) { text += m_cubeGrid.ToString() + " "; } if (MyDebugDrawSettings.DEBUG_DRAW_GRID_CONTROL) { var controllingPlayer = Sync.Players.GetControllingPlayer(m_cubeGrid); if (controllingPlayer != null) { text += "Controlled by: " + controllingPlayer.DisplayName; color = Color.LightGreen; } } MyRenderProxy.DebugDrawText3D(m_cubeGrid.PositionComp.WorldAABB.Center, text, color, 0.7f, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); } MyRenderComponentCubeGrid gridRender = m_cubeGrid.Render; if (MyDebugDrawSettings.DEBUG_DRAW_BLOCK_GROUPS) { var tpos = m_cubeGrid.PositionComp.WorldMatrix.Translation; foreach (var group in m_cubeGrid.BlockGroups) { MyRenderProxy.DebugDrawText3D(tpos, group.Name.ToString(), Color.Red, 1, false); tpos += m_cubeGrid.PositionComp.WorldMatrix.Right * group.Name.Length * 0.1f; } } if (MyDebugDrawSettings.DEBUG_DRAW_GRID_DIRTY_BLOCKS) { foreach (var b in m_dirtyBlocks) { var color = m_cubeGrid.GetCubeBlock(b.Key) != null?Color.Red.ToVector3() : Color.Yellow.ToVector3(); var m = Matrix.CreateScale(m_cubeGrid.GridSize) * Matrix.CreateTranslation(b.Key * m_cubeGrid.GridSize) * m_cubeGrid.WorldMatrix; MyRenderProxy.DebugDrawOBB(m, color, 0.15f, false, true); } } // Bone debug draw if (MyDebugDrawSettings.DEBUG_DRAW_DISPLACED_BONES) { Vector3 cameraPos = (Vector3)MySector.MainCamera.Position; foreach (var bone in m_cubeGrid.Skeleton.Bones) { var bonePos = (bone.Key / (float)m_cubeGrid.Skeleton.BoneDensity) * gridRender.GridSize + bone.Value; bonePos -= new Vector3(gridRender.GridSize / m_cubeGrid.Skeleton.BoneDensity); Vector3 pos = Vector3.Transform(bonePos, (Matrix)m_cubeGrid.PositionComp.WorldMatrix); MyRenderProxy.DebugDrawSphere(pos, 0.05f, Color.Red.ToVector3(), 0.5f, false, true); if ((cameraPos - pos).LengthSquared() < 200.0f) { MyRenderProxy.DebugDrawText3D(pos, bone.Key.ToString(), Color.Red, 0.4f, false); } } } if (MyDebugDrawSettings.DEBUG_DRAW_STRUCTURAL_INTEGRITY && m_cubeGrid.StructuralIntegrity != null) { m_cubeGrid.StructuralIntegrity.DebugDraw(); } if (MyDebugDrawSettings.DEBUG_DRAW_CUBES) { foreach (var cubeBlock in m_cubeGrid.CubeBlocks) { var cb = cubeBlock.FatBlock; if (cb == null) { continue; } cb.DebugDraw(); } } m_cubeGrid.GridSystems.DebugDraw(); if (MyDebugDrawSettings.DEBUG_DRAW_GRID_TERMINAL_SYSTEMS) { /* if (grid.OnBlockAdded != null) * { * MyRenderProxy.DebugDrawText3D(Entity.PositionComp.WorldMatrix.Translation + new Vector3(0.0f, 0.0f, 0.5f), grid.OnBlockAdded.GetInvocationList().Count().ToString(), Color.NavajoWhite, 1.0f, false); * }*/ } if (MyFakes.ENABLE_TRASH_REMOVAL && MyDebugDrawSettings.DEBUG_DRAW_TRASH_REMOVAL) { bool isTrash = m_cubeGrid.IsTrash(); Color color = isTrash ? Color.Red : Color.Green; float sphereRadius = m_cubeGrid.PositionComp.LocalAABB.HalfExtents.AbsMax(); Vector3D com = m_cubeGrid.Physics != null ? m_cubeGrid.Physics.CenterOfMassWorld : m_cubeGrid.PositionComp.WorldMatrix.Translation; MyRenderProxy.DebugDrawSphere(com, sphereRadius, color, 1.0f, false); } if (MyDebugDrawSettings.DEBUG_DRAW_GRID_ORIGINS) { MyRenderProxy.DebugDrawAxis(m_cubeGrid.PositionComp.WorldMatrix, 1.0f, false); } if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW && MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS_ALL) { foreach (MySlimBlock block in m_cubeGrid.GetBlocks()) { if ((m_cubeGrid.GridIntegerToWorld(block.Position) - MySector.MainCamera.Position).LengthSquared() < 200) { DebugDrawMountPoints(block); } } } if (MyDebugDrawSettings.DEBUG_DRAW_BLOCK_INTEGRITY) { if (MySector.MainCamera != null && (MySector.MainCamera.Position - m_cubeGrid.PositionComp.WorldVolume.Center).Length() < 16 + m_cubeGrid.PositionComp.WorldVolume.Radius) { foreach (var cubeBlock in m_cubeGrid.CubeBlocks) { var pos = m_cubeGrid.GridIntegerToWorld(cubeBlock.Position); if (m_cubeGrid.GridSizeEnum == MyCubeSize.Large || (MySector.MainCamera != null && (MySector.MainCamera.Position - pos).LengthSquared() < 9)) { float integrity = 0; if (cubeBlock.FatBlock is MyCompoundCubeBlock) { foreach (var b in (cubeBlock.FatBlock as MyCompoundCubeBlock).GetBlocks()) { integrity += b.Integrity * b.BlockDefinition.MaxIntegrityRatio; } } else { integrity = cubeBlock.Integrity * cubeBlock.BlockDefinition.MaxIntegrityRatio; } MyRenderProxy.DebugDrawText3D(m_cubeGrid.GridIntegerToWorld(cubeBlock.Position), ((int)integrity).ToString(), Color.White, m_cubeGrid.GridSizeEnum == MyCubeSize.Large ? 0.65f : 0.5f, false); } } } } base.DebugDraw(); }
/// <summary> /// Adds the vertices from the physical body (rock) that is inside the given OBB /// </summary> /// <param name="voxelMap"></param> /// <param name="border"></param> /// <param name="originPosition"></param> /// <param name="obb"></param> /// <param name="bbList"></param> private void AddVoxelVertices(MyVoxelMap voxelMap, float border, Vector3D originPosition, MyOrientedBoundingBoxD obb, List<BoundingBoxD> bbList) { AddVoxelMesh(voxelMap, voxelMap.Storage, null, border, originPosition, obb, bbList); }
private static int RemoveStations(MySessionComponentEconomy meh, List <MyFaction> factionList, bool deleteFaction = false) { var removedStations = 0; var removeStationList = new List <MyFaction>(); var deletedStationPositions = new List <MyOrientedBoundingBoxD>(); foreach (var faction in factionList) { foreach (var station in faction.Stations) { MyEntities.TryGetEntityById(station.StationEntityId, out var entity); if (entity != null) { deletedStationPositions.Add(new MyOrientedBoundingBoxD(entity.PositionComp.LocalAABB, entity.PositionComp.WorldMatrixRef)); entity.Close(); } meh.RemoveStationGrid(station.Id); meh.RemoveStationGrid(station.StationEntityId); removeStationList.Add(faction); removedStations++; } } RemoveStation(removeStationList); //Cleanup safezones of deleted stations using position. var safeZones = new HashSet <MySafeZone>(MySessionComponentSafeZones.SafeZones); var delSafeZones = new List <MySafeZone>(); foreach (var zone in safeZones) { var zonePosition = new MyOrientedBoundingBoxD(zone.PositionComp.LocalAABB, zone.PositionComp.WorldMatrixRef); foreach (var position in deletedStationPositions) { if (!position.Intersects(ref zonePosition)) { continue; } delSafeZones.Add(zone); break; } } foreach (var zone in delSafeZones) { zone.Close(); } if (!deleteFaction) { CleanupReputations(); return(removedStations); } foreach (var faction in factionList) { RemoveFaction(faction); } CleanupReputations(); return(removedStations); }
private void AddVoxelMesh(MyVoxelBase voxelBase, IMyStorage storage, Dictionary<Vector3I, MyIsoMesh> cache, float border, Vector3D originPosition, MyOrientedBoundingBoxD obb, List<BoundingBoxD> bbList) { bool useCache = cache != null; if (useCache) CheckCacheValidity(); obb.HalfExtent += new Vector3D(border, 0, border); BoundingBoxD bb = obb.GetAABB(); int aabbSideSide = (int)Math.Round(bb.HalfExtents.Max() * 2); bb = new BoundingBoxD(bb.Min, bb.Min + aabbSideSide); bb.Translate(obb.Center - bb.Center); // For debug bbList.Add(new BoundingBoxD(bb.Min, bb.Max)); bb = (BoundingBoxD)bb.TransformFast(voxelBase.PositionComp.WorldMatrixInvScaled); bb.Translate(voxelBase.SizeInMetresHalf); Vector3I min = Vector3I.Round(bb.Min); Vector3I max = min + aabbSideSide; Vector3I geomMin, geomMax; MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref min, out geomMin); MyVoxelCoordSystems.VoxelCoordToGeometryCellCoord(ref max, out geomMax); var cullBox = obb; cullBox.Transform(voxelBase.PositionComp.WorldMatrixInvScaled); cullBox.Center += voxelBase.SizeInMetresHalf; ProfilerShort.Begin("WOOOORK"); Vector3I_RangeIterator it = new Vector3I_RangeIterator(ref geomMin, ref geomMax); MyCellCoord coord = new MyCellCoord(); BoundingBox localAabb; coord.Lod = NAVMESH_LOD; int hits = 0; MyIsoMesh gMesh; Vector3 offset = originPosition - voxelBase.PositionLeftBottomCorner; // Calculate rotation Vector3 gravityVector = -Vector3.Normalize(GameSystems.MyGravityProviderSystem.CalculateTotalGravityInPoint(originPosition)); Vector3 forwardVector = Vector3.CalculatePerpendicularVector(gravityVector); Quaternion quaternion = Quaternion.CreateFromForwardUp(forwardVector, gravityVector); Matrix rotation = Matrix.CreateFromQuaternion(Quaternion.Inverse(quaternion)); Matrix ownRotation = voxelBase.PositionComp.WorldMatrix.GetOrientation(); while (it.IsValid()) { ProfilerShort.Begin("ITERATOR"); if (useCache && cache.TryGetValue(it.Current, out gMesh)) { if (gMesh != null) { AddMeshTriangles(gMesh, offset, rotation, ownRotation); } it.MoveNext(); ProfilerShort.End(); continue; } coord.CoordInLod = it.Current; MyVoxelCoordSystems.GeometryCellCoordToLocalAABB(ref coord.CoordInLod, out localAabb); if (!cullBox.Intersects(ref localAabb)) { hits++; it.MoveNext(); ProfilerShort.End(); continue; } ProfilerShort.End(); var debugBB = new BoundingBoxD(localAabb.Min, localAabb.Max).Translate(-voxelBase.SizeInMetresHalf); bbList.Add(debugBB); ProfilerShort.Begin("Mesh Calc"); var voxelStart = coord.CoordInLod * MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS - 1; var voxelEnd = voxelStart + MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_VOXELS //- 1 + 1 // overlap to neighbor so geometry is stitched together within same LOD + 1; // for eg. 9 vertices in row we need 9 + 1 samples (voxels) var generatedMesh = MyPrecalcComponent.IsoMesher.Precalc(storage, NAVMESH_LOD, voxelStart, voxelEnd, false, false, true); ProfilerShort.End(); if (useCache) cache[it.Current] = generatedMesh; if (generatedMesh != null) { ProfilerShort.Begin("Mesh NOT NULL"); AddMeshTriangles(generatedMesh, offset, rotation, ownRotation); ProfilerShort.End(); } it.MoveNext(); } ProfilerShort.End(); }
protected override void DoDetection(bool useHead) { ProfilerShort.Begin("DoDetection"); if (Character == MySession.Static.ControlledEntity) { MyHud.SelectedObjectHighlight.RemoveHighlight(); } var head = Character.GetHeadMatrix(false); var headPos = head.Translation - (Vector3D)head.Forward * 0.3; // Move to center of head, we don't want eyes (in front of head) Vector3D from; Vector3D dir; if (!useHead) { //Ondrej version var cameraMatrix = MySector.MainCamera.WorldMatrix; dir = cameraMatrix.Forward; from = MyUtils.LinePlaneIntersection(headPos, (Vector3)dir, cameraMatrix.Translation, (Vector3)dir); } else { //Petr version dir = head.Forward; from = headPos; } Vector3D to = from + dir * MyConstants.DEFAULT_INTERACTIVE_DISTANCE; //EnableDetectorsInArea(from); GatherDetectorsInArea(from); float closestDetector = float.MaxValue; IMyEntity closestEntity = null; IMyUseObject closestInteractive = null; foreach (var entity in m_detectableEntities) { if (entity == Character) { continue; } var use = entity.Components.Get <MyUseObjectsComponentBase>() as MyUseObjectsComponent; if (use != null) { float detectorDistance; var interactive = use.RaycastDetectors(from, to, out detectorDistance); if (Math.Abs(detectorDistance) < Math.Abs(closestDetector)) { closestDetector = detectorDistance; closestEntity = entity; closestInteractive = interactive; } } //Floating object handling - give FO useobject component! var use2 = entity as IMyUseObject; if (use2 != null) { var m = use2.ActivationMatrix; var ray = new RayD(from, to - from); var obb = new MyOrientedBoundingBoxD(m); var dist = obb.Intersects(ref ray); if (dist.HasValue && Math.Abs(dist.Value) < Math.Abs(closestDetector)) { closestDetector = (float)dist.Value; closestEntity = entity; closestInteractive = use2; } } } m_detectableEntities.Clear(); //VRageRender.MyRenderProxy.DebugDrawLine3D(from, to, Color.Red, Color.Green, true); //VRageRender.MyRenderProxy.DebugDrawSphere(headPos, 0.05f, Color.Red.ToVector3(), 1.0f, false); StartPosition = from; MyPhysics.CastRay(from, to, m_hits, MyPhysics.CollisionLayers.FloatingObjectCollisionLayer); bool hasInteractive = false; int index = 0; while (index < m_hits.Count && (m_hits[index].HkHitInfo.Body == null || m_hits[index].HkHitInfo.GetHitEntity() == Character || m_hits[index].HkHitInfo.GetHitEntity() == null || m_hits[index].HkHitInfo.Body.HasProperty(HkCharacterRigidBody.MANIPULATED_OBJECT) || m_hits[index].HkHitInfo.Body.Layer == MyPhysics.CollisionLayers.VoxelLod1CollisionLayer)) // Skip invalid hits and self character { index++; } if (index < m_hits.Count && m_hits[index].HkHitInfo.HitFraction > closestDetector - 0.05f)//compensation { // TODO: Uncomment to enforce that character must face object by front to activate it //if (TestInteractionDirection(head.Forward, h.Position - GetPosition())) //return; HitPosition = from + dir * closestDetector; MyUseObjectsComponentBase useObject; if (closestEntity.Components.TryGet <MyUseObjectsComponentBase>(out useObject)) { var detectorPhysics = useObject.DetectorPhysics; HitMaterial = detectorPhysics.GetMaterialAt(HitPosition); HitBody = ((MyPhysicsBody)detectorPhysics).RigidBody; } else { HitMaterial = closestEntity.Physics.GetMaterialAt(HitPosition); HitBody = ((MyPhysicsBody)closestEntity.Physics).RigidBody; } DetectedEntity = closestEntity; var interactive = closestInteractive; if (UseObject != null && interactive != null && UseObject != interactive) { UseObject.OnSelectionLost(); } //if (interactive != null && interactive.SupportedActions != UseActionEnum.None && (Vector3D.Distance(from, (Vector3D)h.Position)) < interactive.InteractiveDistance && Character == MySession.Static.ControlledEntity) if (interactive != null && interactive.SupportedActions != UseActionEnum.None && closestDetector * MyConstants.DEFAULT_INTERACTIVE_DISTANCE < interactive.InteractiveDistance && Character == MySession.Static.ControlledEntity) { HandleInteractiveObject(interactive); UseObject = interactive; hasInteractive = true; } } if (!hasInteractive) { if (UseObject != null) { UseObject.OnSelectionLost(); } UseObject = null; } ProfilerShort.End(); }
/// <summary> /// Returns the specified corner from the OBB. /// </summary> /// <param name="obb"></param> /// <param name="corner"></param> /// <returns>Returns the </returns> public static Vector3D GetOBBCorner(MyOrientedBoundingBoxD obb, OBBCorner corner) { Vector3D[] corners = new Vector3D[8]; obb.GetCorners(corners, 0); return corners[(int)corner]; }
public static void DebugDrawClusters() { if (Clusters == null) { return; } double previewScale = 2000; MatrixD previewMatrix = MatrixD.CreateWorld(DebugDrawClustersMatrix.Translation + previewScale * DebugDrawClustersMatrix.Forward, Vector3D.Forward, Vector3D.Up); m_resultWorlds.Clear(); Clusters.GetAll(m_resultWorlds); BoundingBoxD totalBox = BoundingBoxD.CreateInvalid(); foreach (var res in m_resultWorlds) { totalBox = totalBox.Include(res.AABB); } double maxAxis = totalBox.Size.AbsMax(); //double scaleAxis = 0.057142857142857141; double scaleAxis = previewScale / maxAxis; //Vector3D scale = new Vector3D(totalBox.Size.X * scaleAxis, totalBox.Size.Y * scaleAxis, totalBox.Size.Z * scaleAxis); Vector3D center = totalBox.Center; totalBox.Min -= center; totalBox.Max -= center; { BoundingBoxD scaledBox = new BoundingBoxD(totalBox.Min * scaleAxis * 1.02f, totalBox.Max * scaleAxis * 1.02f); MyOrientedBoundingBoxD oriented = new MyOrientedBoundingBoxD(scaledBox, previewMatrix); MyRenderProxy.DebugDrawOBB(oriented, Vector3.Up, 1, false, false); MyRenderProxy.DebugDrawAxis(previewMatrix, 50, false); if (MySession.Static != null) { foreach (var player in Sandbox.Game.Multiplayer.Sync.Players.GetOnlinePlayers()) { if (player.Character != null) { var playerPos = Vector3D.Transform((player.Character.PositionComp.GetPosition() - center) * scaleAxis, previewMatrix); MyRenderProxy.DebugDrawSphere(playerPos, 10, Vector3.One, 1, false); } } } } Clusters.GetAllStaticObjects(m_clusterStaticObjects); foreach (var staticBB in m_clusterStaticObjects) { BoundingBoxD scaledBox = new BoundingBoxD((staticBB.Min - center) * scaleAxis, (staticBB.Max - center) * scaleAxis); MyOrientedBoundingBoxD oriented = new MyOrientedBoundingBoxD(scaledBox, previewMatrix); MyRenderProxy.DebugDrawOBB(oriented, Color.Blue, 1, false, false); } foreach (var res in m_resultWorlds) { BoundingBoxD scaledBox = new BoundingBoxD((res.AABB.Min - center) * scaleAxis, (res.AABB.Max - center) * scaleAxis); MyOrientedBoundingBoxD oriented = new MyOrientedBoundingBoxD(scaledBox, previewMatrix); MyRenderProxy.DebugDrawOBB(oriented, Vector3.One, 1, false, false); foreach (var rb in ((HkWorld)res.UserData).CharacterRigidBodies) { Vector3D rbCenter = res.AABB.Center + rb.Position; rbCenter = (rbCenter - center) * scaleAxis; rbCenter = Vector3D.Transform(rbCenter, previewMatrix); Vector3D velocity = rb.LinearVelocity; velocity = Vector3D.TransformNormal(velocity, previewMatrix) * 10; MyRenderProxy.DebugDrawLine3D(rbCenter, rbCenter + velocity, Color.Blue, Color.White, false); } foreach (var rb in ((HkWorld)res.UserData).RigidBodies) { MyOrientedBoundingBoxD rbbb = new MyOrientedBoundingBoxD((BoundingBoxD)rb.GetEntity().LocalAABB, rb.GetEntity().WorldMatrix); rbbb.Center = (rbbb.Center - center) * scaleAxis; rbbb.HalfExtent *= scaleAxis; rbbb.Transform(previewMatrix); MyRenderProxy.DebugDrawOBB(rbbb, Color.Yellow, 1, false, false); //BoundingBoxD rbaa = rb.GetEntity().WorldAABB; //rbaa.Min = (rbaa.Min - center) * scaleAxis; //rbaa.Max = (rbaa.Max - center) * scaleAxis; //MyRenderProxy.DebugDrawAABB(rbaa, new Vector3(0.8f, 0.8f, 0.8f), 1, 1, false); Vector3D velocity = rb.LinearVelocity; velocity = Vector3D.TransformNormal(velocity, previewMatrix) * 10; MyRenderProxy.DebugDrawLine3D(rbbb.Center, rbbb.Center + velocity, Color.Red, Color.White, false); if (velocity.Length() > 1) { BoundingBoxD ideal = new BoundingBoxD(rb.GetEntity().WorldAABB.Center - MyHavokCluster.IdealClusterSize / 2, rb.GetEntity().WorldAABB.Center + MyHavokCluster.IdealClusterSize / 2); MyOrientedBoundingBoxD idealObb = new MyOrientedBoundingBoxD(ideal, MatrixD.Identity); idealObb.Center = (ideal.Center - center) * scaleAxis; idealObb.HalfExtent *= scaleAxis; idealObb.Transform(previewMatrix); MyRenderProxy.DebugDrawOBB(idealObb, new Vector3(0, 0, 1), 1, false, false); } } } }
public override void DebugDraw() { if (MyDebugDrawSettings.DEBUG_DRAW_CONSTRAINTS) { int i = 0; foreach (var c in Constraints) { if (c.IsDisposed) continue; Color col = Color.Green; if (!IsConstraintValid(c)) col = Color.Red; Vector3 pivotA, pivotB; c.GetPivotsInWorld(out pivotA, out pivotB); var pos = ClusterToWorld(pivotA); MyRenderProxy.DebugDrawSphere(pos, 0.2f, col, 1, false); MyRenderProxy.DebugDrawText3D(pos, i.ToString(), Color.White, 0.7f, true); i++; pos = ClusterToWorld(pivotB); MyRenderProxy.DebugDrawSphere(pos, 0.2f, col, 1, false); } } if (MyDebugDrawSettings.DEBUG_DRAW_INERTIA_TENSORS && RigidBody != null) { var com = ClusterToWorld(RigidBody.CenterOfMassWorld); VRageRender.MyRenderProxy.DebugDrawLine3D(com, com + RigidBody.AngularVelocity, Color.Blue, Color.Red, false); var invMass = 1/RigidBody.Mass; var diag = RigidBody.InertiaTensor.Scale; var betSq = (diag.X - diag.Y + diag.Z) * invMass * 6; var gamaSq = diag.X * invMass * 12 - betSq; var alpSq = diag.Z * invMass * 12 - betSq; var scale = 1.01f * 0.5f; var he = new Vector3(Math.Sqrt(alpSq), Math.Sqrt(betSq), Math.Sqrt(gamaSq)) * scale; MyOrientedBoundingBoxD obb = new MyOrientedBoundingBoxD(new BoundingBoxD(-he, he), MatrixD.Identity); obb.Transform(RigidBody.GetRigidBodyMatrix()); obb.Center = CenterOfMassWorld;// RigidBody.GetBody().ClusterToWorld(RigidBody.CenterOfMassWorld); VRageRender.MyRenderProxy.DebugDrawOBB(obb, Color.Purple, 0.05f, false, false); //VRageRender.MyRenderProxy.DebugDrawText3D(obb.Center, Entity.ToString(), Color.Purple, 0.5f, false); } if (MyDebugDrawSettings.DEBUG_DRAW_PHYSICS_SHAPES && !IsWelded) { const float alpha = 0.3f; //if (!Enabled) // return; var offset = MyPhysics.Clusters.GetObjectOffset(ClusterObjectID); if (RigidBody != null && BreakableBody != null) { Vector3D com = Vector3D.Transform((Vector3D)BreakableBody.BreakableShape.CoM, RigidBody.GetRigidBodyMatrix()) + offset; Color color = RigidBody.GetMotionType() != Havok.HkMotionType.Box_Inertia ? Color.Gray : RigidBody.IsActive ? Color.Red : Color.Blue; VRageRender.MyRenderProxy.DebugDrawSphere(RigidBody.CenterOfMassWorld + offset, 0.2f, color, 1, false); VRageRender.MyRenderProxy.DebugDrawAxis(Entity.PositionComp.WorldMatrix, 0.2f, false); } int index; if (RigidBody != null) { index = 0; Matrix rbMatrix = RigidBody.GetRigidBodyMatrix(); MatrixD worldMatrix = MatrixD.CreateWorld(rbMatrix.Translation + offset, rbMatrix.Forward, rbMatrix.Up); MyPhysicsDebugDraw.DrawCollisionShape(RigidBody.GetShape(), worldMatrix, alpha, ref index); } if (RigidBody2 != null) { index = 0; Matrix rbMatrix = RigidBody2.GetRigidBodyMatrix(); MatrixD worldMatrix = MatrixD.CreateWorld(rbMatrix.Translation + offset, rbMatrix.Forward, rbMatrix.Up); MyPhysicsDebugDraw.DrawCollisionShape(RigidBody2.GetShape(), worldMatrix, alpha, ref index); } if (CharacterProxy != null) { index = 0; //MatrixD characterTransform = MatrixD.CreateWorld(CharacterProxy.Position + offset, CharacterProxy.Forward, CharacterProxy.Up); Matrix rbMatrix = CharacterProxy.GetRigidBodyTransform(); MatrixD worldMatrix = MatrixD.CreateWorld(rbMatrix.Translation + offset, rbMatrix.Forward, rbMatrix.Up); MyPhysicsDebugDraw.DrawCollisionShape(CharacterProxy.GetShape(), worldMatrix, alpha, ref index); } } }
public void DebugDraw() { MatrixD mat = MatrixD.Invert(m_worldInv); Quaternion orientation = Quaternion.CreateFromRotationMatrix(mat.GetOrientation()); foreach (var segment in m_segments) { Vector3D halfExtents = new Vector3D(segment.Size) * 0.51; Vector3D center = new Vector3D(segment.Min + segment.Max) * 0.5; center = Vector3D.Transform(center, mat); var obb = new MyOrientedBoundingBoxD(center, halfExtents, orientation); MyRenderProxy.DebugDrawOBB(obb, Color.Red, 0.5f, false, false); } }
public static void DrawMountPoints(float cubeSize, MyCubeBlockDefinition def, MatrixD drawMatrix, MyCubeBlockDefinition.MountPoint[] mountPoints) { Color color = Color.Yellow; Vector3I centerGrid = def.Center; Vector3 centerOffset = def.Size * 0.5f; Matrix drawTransf = MatrixD.CreateTranslation((centerGrid - centerOffset) * cubeSize) * drawMatrix; // Visualize existing mount points as yellow cuboids for (int i = 0; i < mountPoints.Length; ++i) { if (mountPoints[i].Normal == Base6Directions.IntDirections[0] && !MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS_AXIS0) continue; if (mountPoints[i].Normal == Base6Directions.IntDirections[1] && !MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS_AXIS1) continue; if (mountPoints[i].Normal == Base6Directions.IntDirections[2] && !MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS_AXIS2) continue; if (mountPoints[i].Normal == Base6Directions.IntDirections[3] && !MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS_AXIS3) continue; if (mountPoints[i].Normal == Base6Directions.IntDirections[4] && !MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS_AXIS4) continue; if (mountPoints[i].Normal == Base6Directions.IntDirections[5] && !MyDebugDrawSettings.DEBUG_DRAW_MOUNT_POINTS_AXIS5) continue; var start = mountPoints[i].Start - centerGrid; var end = mountPoints[i].End - centerGrid; var box = new BoundingBoxD(Vector3.Min(start, end) * cubeSize, Vector3.Max(start, end) * cubeSize); //MySimpleObjectDraw.DrawTransparentBox(ref drawTransf, ref box, ref color, MySimpleObjectRasterizer.SolidAndWireframe, 1, 0.1f); MyOrientedBoundingBoxD boxD = new MyOrientedBoundingBoxD(box, drawTransf); VRageRender.MyRenderProxy.DebugDrawOBB(boxD, color, 0.2f, true, false); } }
public void DebugDraw() { var mat = MatrixD.Invert(m_worldInv); MyOrientedBoundingBoxD obb = new MyOrientedBoundingBoxD(MatrixD.CreateScale(m_halfExtents) * mat); MyRenderProxy.DebugDrawOBB(obb, Color.Red, 0.3f, false, false); }
public void CalculateRotationHints(MatrixD drawMatrix, BoundingBoxD worldBox, bool draw, bool fixedAxes = false, bool hideForwardAndUpArrows = false) { drawMatrix.Translation = Vector3D.Zero; MatrixD drawInverse = MatrixD.Invert(drawMatrix); drawInverse *= drawMatrix.GetOrientation(); drawInverse *= MySector.MainCamera.ViewMatrixAtZero; MatrixD camWorld = MatrixD.Invert(drawInverse); //MatrixD.Invert(MySector.MainCamera.ViewMatrixAtZero)*MatrixD.Invert(drawMatrix.GetOrientation())*drawMatrix; m_viewProjection.ViewAtZero = MatrixD.CreateLookAt(Vector3D.Zero, camWorld.Forward, camWorld.Up); m_viewProjection.ViewAtZero.Translation = new Vector3D(0,0,-6); m_viewProjection.View = drawInverse; m_viewProjection.View.Translation += new Vector3D(0, 0, -6); m_viewProjection.CameraPosition = camWorld.Translation; Vector2 screenSize = MyGuiManager.GetScreenSizeFromNormalizedSize(Vector2.One); float previewRatio = 2.5f; int hintsWidth = (int)(screenSize.X / previewRatio), hintsHeight = (int)(screenSize.Y / previewRatio), hintsXOffset = 0, hintsYOffset = 0; m_viewProjection.Viewport = new MyViewport( (int)MySector.MainCamera.Viewport.Width - hintsWidth - hintsXOffset, hintsYOffset, hintsWidth, hintsHeight); m_viewProjection.DepthRead = false; m_viewProjection.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, (float)hintsWidth / hintsHeight, 0.1f, 10); worldBox = new BoundingBoxD(-new Vector3(MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large) * 0.5f), new Vector3(MyDefinitionManager.Static.GetCubeSize(MyCubeSize.Large)) * 0.5f); //m_rotationHintsViewProjection.Projection = MySector.MainCamera.ProjectionMatrix; int projectionId = 0; VRageRender.MyRenderProxy.AddBillboardViewProjection(projectionId, m_viewProjection); //MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, // ref worldBox, ref Vector4.One, MySimpleObjectRasterizer.Wireframe, 1, 0.04f, null, null, false, 0); if (draw) { var white = Color.White; MySimpleObjectDraw.DrawTransparentBox(ref drawMatrix, ref worldBox, ref white, MySimpleObjectRasterizer.Solid, 1, 0.04f, "SquareFullColor", null, false, projectionId, 100); } MyOrientedBoundingBoxD rotateHintsBox = new MyOrientedBoundingBoxD(Vector3D.Transform(worldBox.Center, drawMatrix), worldBox.HalfExtents, Quaternion.CreateFromRotationMatrix(drawMatrix)); //VRageRender.MyRenderProxy.DebugDrawOBB(rotateHintsBox, Vector3.One, 1, false, false); rotateHintsBox.GetCorners(m_cubeVertices, 0); //for (int vi = 0; vi < 8; vi++) //{ // VRageRender.MyRenderProxy.DebugDrawText3D(m_cubeVertices[vi], vi.ToString(), Color.White, 0.7f, false); //} //for (int vi = 0; vi < 4; vi++) //{ // VRageRender.MyRenderProxy.DebugDrawText3D((m_cubeVertices[MyOrientedBoundingBox.StartXVertices[vi]] + m_cubeVertices[MyOrientedBoundingBox.EndXVertices[vi]]) * 0.5f, vi.ToString(), Color.Red, 0.7f, false); // VRageRender.MyRenderProxy.DebugDrawText3D((m_cubeVertices[MyOrientedBoundingBox.StartYVertices[vi]] + m_cubeVertices[MyOrientedBoundingBox.EndYVertices[vi]]) * 0.5f, vi.ToString(), Color.Green, 0.7f, false); // VRageRender.MyRenderProxy.DebugDrawText3D((m_cubeVertices[MyOrientedBoundingBox.StartZVertices[vi]] + m_cubeVertices[MyOrientedBoundingBox.EndZVertices[vi]]) * 0.5f, vi.ToString(), Color.Blue, 0.7f, false); //} int closestXAxis, closestXAxis2; GetClosestCubeEdge(m_cubeVertices, MyOrientedBoundingBox.StartXVertices, MyOrientedBoundingBox.EndXVertices, out closestXAxis, out closestXAxis2); Vector3D startXVertex = m_cubeVertices[MyOrientedBoundingBox.StartXVertices[closestXAxis]]; Vector3D endXVertex = m_cubeVertices[MyOrientedBoundingBox.EndXVertices[closestXAxis]]; Vector3D startXVertex2 = m_cubeVertices[MyOrientedBoundingBox.StartXVertices[closestXAxis2]]; Vector3D endXVertex2 = m_cubeVertices[MyOrientedBoundingBox.EndXVertices[closestXAxis2]]; int closestYAxis, closestYAxis2; GetClosestCubeEdge(m_cubeVertices, MyOrientedBoundingBox.StartYVertices, MyOrientedBoundingBox.EndYVertices, out closestYAxis, out closestYAxis2); Vector3D startYVertex = m_cubeVertices[MyOrientedBoundingBox.StartYVertices[closestYAxis]]; Vector3D endYVertex = m_cubeVertices[MyOrientedBoundingBox.EndYVertices[closestYAxis]]; Vector3D startYVertex2 = m_cubeVertices[MyOrientedBoundingBox.StartYVertices[closestYAxis2]]; Vector3D endYVertex2 = m_cubeVertices[MyOrientedBoundingBox.EndYVertices[closestYAxis2]]; int closestZAxis, closestZAxis2; GetClosestCubeEdge(m_cubeVertices, MyOrientedBoundingBox.StartZVertices, MyOrientedBoundingBox.EndZVertices, out closestZAxis, out closestZAxis2); Vector3D startZVertex = m_cubeVertices[MyOrientedBoundingBox.StartZVertices[closestZAxis]]; Vector3D endZVertex = m_cubeVertices[MyOrientedBoundingBox.EndZVertices[closestZAxis]]; Vector3D startZVertex2 = m_cubeVertices[MyOrientedBoundingBox.StartZVertices[closestZAxis2]]; Vector3D endZVertex2 = m_cubeVertices[MyOrientedBoundingBox.EndZVertices[closestZAxis2]]; m_cubeEdges.Clear(); m_cubeEdges.Add(new BoxEdge() { Axis = 0, Edge = new LineD(startXVertex, endXVertex) }); m_cubeEdges.Add(new BoxEdge() { Axis = 1, Edge = new LineD(startYVertex, endYVertex) }); m_cubeEdges.Add(new BoxEdge() { Axis = 2, Edge = new LineD(startZVertex, endZVertex) }); if (!fixedAxes) { int rotDirection; RotationRightAxis = GetBestAxis(m_cubeEdges, MySector.MainCamera.WorldMatrix.Right, out rotDirection); RotationRightDirection = rotDirection; RotationUpAxis = GetBestAxis(m_cubeEdges, MySector.MainCamera.WorldMatrix.Up, out rotDirection); RotationUpDirection = rotDirection; RotationForwardAxis = GetBestAxis(m_cubeEdges, MySector.MainCamera.WorldMatrix.Forward, out rotDirection); RotationForwardDirection = rotDirection; } string rightControlName1 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_HORISONTAL_POSITIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard).ToString(); string rightControlName2 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_HORISONTAL_NEGATIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard).ToString(); string upControlName1 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_VERTICAL_POSITIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard).ToString(); string upControlName2 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_VERTICAL_NEGATIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard).ToString(); string forwControlName1 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_ROLL_POSITIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard).ToString(); string forwControlName2 = MyInput.Static.GetGameControl(MyControlsSpace.CUBE_ROTATE_ROLL_NEGATIVE).GetControlButtonName(MyGuiInputDeviceEnum.Keyboard).ToString(); if (MyInput.Static.IsJoystickConnected()) { rightControlName1 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_HORISONTAL_POSITIVE).ToString(); rightControlName2 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_HORISONTAL_NEGATIVE).ToString(); upControlName1 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_VERTICAL_POSITIVE).ToString(); upControlName2 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_VERTICAL_NEGATIVE).ToString(); forwControlName1 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_ROLL_POSITIVE).ToString(); forwControlName2 = MyControllerHelper.GetCodeForControl(MySpaceBindingCreator.CX_BUILD_MODE, MyControlsSpace.CUBE_ROTATE_ROLL_NEGATIVE).ToString(); } Vector3D rightStart = Vector3D.Zero; Vector3D rightEnd = Vector3D.Zero; Vector3D upStart = Vector3D.Zero; Vector3D upEnd = Vector3D.Zero; Vector3D forwStart = Vector3D.Zero; Vector3D forwEnd = Vector3D.Zero; Vector3D rightStart2 = Vector3D.Zero; Vector3D rightEnd2 = Vector3D.Zero; Vector3D upStart2 = Vector3D.Zero; Vector3D upEnd2 = Vector3D.Zero; Vector3D forwStart2 = Vector3D.Zero; Vector3D forwEnd2 = Vector3D.Zero; int rightAxis = -1, upAxis = -1, forwAxis = -1; int closestRightEdge = -1, closestUpEdge = -1, closestForwEdge = -1; int closestRightEdge2 = -1, closestUpEdge2 = -1, closestForwEdge2 = -1; if (RotationRightAxis == 0) { rightStart = startXVertex; rightEnd = endXVertex; rightStart2 = startXVertex2; rightEnd2 = endXVertex2; rightAxis = 0; closestRightEdge = closestXAxis; closestRightEdge2 = closestXAxis2; } else if (RotationRightAxis == 1) { rightStart = startYVertex; rightEnd = endYVertex; rightStart2 = startYVertex2; rightEnd2 = endYVertex2; rightAxis = 1; closestRightEdge = closestYAxis; closestRightEdge2 = closestYAxis2; } else if (RotationRightAxis == 2) { rightStart = startZVertex; rightEnd = endZVertex; rightStart2 = startZVertex2; rightEnd2 = endZVertex2; rightAxis = 2; closestRightEdge = closestZAxis; closestRightEdge2 = closestZAxis2; } else { System.Diagnostics.Debug.Assert(false, "Not defined axis"); } if (RotationUpAxis == 0) { upStart = startXVertex; upEnd = endXVertex; upStart2 = startXVertex2; upEnd2 = endXVertex2; upAxis = 0; closestUpEdge = closestXAxis; closestUpEdge2 = closestXAxis2; } else if (RotationUpAxis == 1) { upStart = startYVertex; upEnd = endYVertex; upStart2 = startYVertex2; upEnd2 = endYVertex2; upAxis = 1; closestUpEdge = closestYAxis; closestUpEdge2 = closestYAxis2; } else if (RotationUpAxis == 2) { upStart = startZVertex; upEnd = endZVertex; upStart2 = startZVertex2; upEnd2 = endZVertex2; upAxis = 2; closestUpEdge = closestZAxis; closestUpEdge2 = closestZAxis2; } if (RotationForwardAxis == 0) { forwStart = startXVertex; forwEnd = endXVertex; forwStart2 = startXVertex2; forwEnd2 = endXVertex2; forwAxis = 0; closestForwEdge = closestXAxis; closestForwEdge2 = closestXAxis2; } else if (RotationForwardAxis == 1) { forwStart = startYVertex; forwEnd = endYVertex; forwStart2 = startYVertex2; forwEnd2 = endYVertex2; forwAxis = 1; closestForwEdge = closestYAxis; closestForwEdge2 = closestYAxis2; } else if (RotationForwardAxis == 2) { forwStart = startZVertex; forwEnd = endZVertex; forwStart2 = startZVertex2; forwEnd2 = endZVertex2; forwAxis = 2; closestForwEdge = closestZAxis; closestForwEdge2 = closestZAxis2; } float textScale = 0.7f; //Closest axis //VRageRender.MyRenderProxy.DebugDrawLine3D(rightStart, rightEnd, Color.Red, Color.Red, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(upStart, upEnd, Color.Green, Color.Green, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(forwStart, forwEnd, Color.Blue, Color.Blue, false); if (draw) { //if all axis are visible, all are shown on edges //if 1 axis is not visible, other 2 must be shown on faces //if 2 are not visible, they are shown on faces and the one is shown on face center //Vector3 camVector = Vector3.Normalize(rotateHintsBox.Center - MySector.MainCamera.Position); Vector3D camVector = MySector.MainCamera.ForwardVector; Vector3D rightDirection = Vector3.Normalize(rightEnd - rightStart); Vector3D upDirection = Vector3.Normalize(upEnd - upStart); Vector3D forwDirection = Vector3.Normalize(forwEnd - forwStart); float dotRight = Math.Abs(Vector3.Dot(camVector, rightDirection)); float dotUp = Math.Abs(Vector3.Dot(camVector, upDirection)); float dotForw = Math.Abs(Vector3.Dot(camVector, forwDirection)); bool drawRightOnFace = false, drawUpOnFace = false, drawForwOnFace = false; bool drawRightOnFaceCenter = false, drawUpOnFaceCenter = false, drawForwOnFaceCenter = false; float dotAngle = 0.4f; if (dotRight < dotAngle) { if (dotUp < dotAngle) { drawForwOnFaceCenter = true; drawRightOnFace = true; drawUpOnFace = true; System.Diagnostics.Debug.Assert(dotForw >= dotAngle); } else if (dotForw < dotAngle) { drawUpOnFaceCenter = true; drawRightOnFace = true; drawForwOnFace = true; System.Diagnostics.Debug.Assert(dotUp >= dotAngle); } else { drawUpOnFace = true; drawForwOnFace = true; } } else if (dotUp < dotAngle) { if (dotRight < dotAngle) { drawForwOnFaceCenter = true; drawRightOnFace = true; drawUpOnFace = true; System.Diagnostics.Debug.Assert(dotForw >= dotAngle); } else if (dotForw < dotAngle) { drawRightOnFaceCenter = true; drawUpOnFace = true; drawForwOnFace = true; System.Diagnostics.Debug.Assert(dotRight >= dotAngle); } else { drawRightOnFace = true; drawForwOnFace = true; } } else if (dotForw < dotAngle) { if (dotRight < dotAngle) { drawUpOnFaceCenter = true; drawRightOnFace = true; drawForwOnFace = true; System.Diagnostics.Debug.Assert(dotUp >= dotAngle); } else if (dotUp < dotAngle) { drawUpOnFaceCenter = true; drawRightOnFace = true; drawForwOnFace = true; System.Diagnostics.Debug.Assert(dotRight >= dotAngle); } else { drawUpOnFace = true; drawRightOnFace = true; } } //Draw according to cube visual appearance if (!(hideForwardAndUpArrows && RotationRightAxis != 1)) { if (drawRightOnFaceCenter) { // VRageRender.MyRenderProxy.DebugDrawSphere((forwStart + forwEnd + forwStart2 + forwEnd2) * 0.25f, 0.2f, Vector3.Right, 1.0f, false, false); Vector3D faceCenter = (forwStart + forwEnd + forwStart2 + forwEnd2) * 0.25f; MyTransparentGeometry.AddBillboardOriented( "ArrowLeftGreen", Vector4.One, faceCenter - RotationForwardDirection * forwDirection * 0.2f - RotationRightDirection * rightDirection * 0.01f, -RotationForwardDirection * forwDirection, -RotationUpDirection * upDirection, 0.2f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowRightGreen", Vector4.One, faceCenter + RotationForwardDirection * forwDirection * 0.2f - RotationRightDirection * rightDirection * 0.01f, RotationForwardDirection * forwDirection, RotationUpDirection * upDirection, 0.2f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(faceCenter - RotationForwardDirection * forwDirection * 0.2f - RotationRightDirection * rightDirection * 0.01f, rightControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(faceCenter + RotationForwardDirection * forwDirection * 0.2f - RotationRightDirection * rightDirection * 0.01f, rightControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } else if (drawRightOnFace) { //VRageRender.MyRenderProxy.DebugDrawLine3D(rightStart2, rightEnd2, Color.Red, Color.Red, false); Vector3 normalRightBack, normalRightForw; MyOrientedBoundingBox.GetNormalBetweenEdges(rightAxis, closestRightEdge, closestRightEdge2, out normalRightForw); Vector3D rightCenter = (rightStart + rightEnd) * 0.5f; Vector3D rightNormalForwWorld = Vector3D.TransformNormal(normalRightForw, drawMatrix); MyOrientedBoundingBox.GetNormalBetweenEdges(rightAxis, closestRightEdge2, closestRightEdge, out normalRightBack); Vector3D rightCenter2 = (rightStart2 + rightEnd2) * 0.5f; Vector3D rightNormalBackWorld = Vector3D.TransformNormal(normalRightBack, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(rightCenter, rightCenter + rightNormalForwWorld, Color.Red, Color.Red, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(rightCenter2, rightCenter2 + rightNormalBackWorld, Color.Red, Color.Red, false); int normalEdge = -1; bool opposite = false; if (closestRightEdge == 0 && closestRightEdge2 == 3) normalEdge = closestRightEdge + 1; else if ((closestRightEdge < closestRightEdge2) || (closestRightEdge == 3 && closestRightEdge2 == 0)) { normalEdge = closestRightEdge - 1; opposite = true; } else normalEdge = closestRightEdge + 1; if (RotationRightDirection < 0) opposite = !opposite; Vector3 rightOffset; MyOrientedBoundingBox.GetNormalBetweenEdges(rightAxis, closestRightEdge, normalEdge, out rightOffset); Vector3D rightOffsetWorld = Vector3D.TransformNormal(rightOffset, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawText3D(rightCenter + rightNormalForwWorld * 0.6f - rightOffsetWorld * 0.01f, opposite ? rightControlName2 : rightControlName1, Color.White, textScale, false); //VRageRender.MyRenderProxy.DebugDrawText3D(rightCenter2 + rightNormalBackWorld * 0.6f - rightOffsetWorld * 0.01f, opposite ? rightControlName1 : rightControlName2, Color.White, textScale, false); MyTransparentGeometry.AddBillboardOriented( "ArrowGreen", Vector4.One, rightCenter + rightNormalForwWorld * 0.4f - rightOffsetWorld * 0.01f, rightNormalBackWorld, rightDirection, 0.5f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowGreen", Vector4.One, rightCenter2 + rightNormalBackWorld * 0.4f - rightOffsetWorld * 0.01f, rightNormalForwWorld, rightDirection, 0.5f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(rightCenter + rightNormalForwWorld * 0.3f - rightOffsetWorld * 0.01f, opposite ? rightControlName1 : rightControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(rightCenter2 + rightNormalBackWorld * 0.3f - rightOffsetWorld * 0.01f, opposite ? rightControlName2 : rightControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } else //draw on edge { Vector3 normalRightBack, normalRightForw; MyOrientedBoundingBox.GetNormalBetweenEdges(rightAxis, closestRightEdge, closestRightEdge + 1, out normalRightForw); MyOrientedBoundingBox.GetNormalBetweenEdges(rightAxis, closestRightEdge, closestRightEdge - 1, out normalRightBack); Vector3D rightCenter = (rightStart + rightEnd) * 0.5f; Vector3D rightNormalForwWorld = Vector3D.TransformNormal(normalRightForw, drawMatrix); Vector3D rightNormalBackWorld = Vector3D.TransformNormal(normalRightBack, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(rightCenter, rightCenter + rightNormalForwWorld, Color.Red, Color.Red, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(rightCenter, rightCenter + rightNormalBackWorld, Color.Red, Color.Red, false); MyTransparentGeometry.AddBillboardOriented( "ArrowGreen", Vector4.One, rightCenter + rightNormalForwWorld * 0.3f - rightNormalBackWorld * 0.01f, rightNormalForwWorld, rightDirection, 0.5f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowGreen", Vector4.One, rightCenter + rightNormalBackWorld * 0.3f - rightNormalForwWorld * 0.01f, rightNormalBackWorld, rightDirection, 0.5f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(rightCenter + rightNormalForwWorld * 0.3f - rightNormalBackWorld * 0.01f, RotationRightDirection < 0 ? rightControlName1 : rightControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(rightCenter + rightNormalBackWorld * 0.3f - rightNormalForwWorld * 0.01f, RotationRightDirection < 0 ? rightControlName2 : rightControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } } if (!(hideForwardAndUpArrows && RotationUpAxis != 1)) { if (drawUpOnFaceCenter) { //VRageRender.MyRenderProxy.DebugDrawSphere((forwStart + forwEnd + forwStart2 + forwEnd2) * 0.25f, 0.2f, Vector3.Up, 1.0f, false, false); Vector3D faceCenter = (forwStart + forwEnd + forwStart2 + forwEnd2) * 0.25f; MyTransparentGeometry.AddBillboardOriented( "ArrowLeftRed", Vector4.One, faceCenter - RotationRightDirection * rightDirection * 0.2f - RotationUpDirection * upDirection * 0.01f, -RotationRightDirection * rightDirection, -RotationForwardDirection * forwDirection, 0.2f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowRightRed", Vector4.One, faceCenter + RotationRightDirection * rightDirection * 0.2f - RotationUpDirection * upDirection * 0.01f, RotationRightDirection * rightDirection, RotationForwardDirection * forwDirection, 0.2f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(faceCenter - RotationRightDirection * rightDirection * 0.2f - RotationUpDirection * upDirection * 0.01f, upControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(faceCenter + RotationRightDirection * rightDirection * 0.2f - RotationUpDirection * upDirection * 0.01f, upControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } else if (drawUpOnFace) { //VRageRender.MyRenderProxy.DebugDrawLine3D(upStart2, upEnd2, Color.Green, Color.Green, false); Vector3 normalUpBack, normalUpForw; MyOrientedBoundingBox.GetNormalBetweenEdges(upAxis, closestUpEdge, closestUpEdge2, out normalUpForw); Vector3D upCenter = (upStart + upEnd) * 0.5f; Vector3 upNormalForwWorld = Vector3.TransformNormal(normalUpForw, drawMatrix); MyOrientedBoundingBox.GetNormalBetweenEdges(upAxis, closestUpEdge2, closestUpEdge, out normalUpBack); Vector3D upCenter2 = (upStart2 + upEnd2) * 0.5f; Vector3 upNormalBackWorld = Vector3.TransformNormal(normalUpBack, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(upCenter, upCenter + upNormalForwWorld, Color.Green, Color.Green, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(upCenter2, upCenter2 + upNormalBackWorld, Color.Green, Color.Green, false); int normalEdge = -1; bool opposite = false; if (closestUpEdge == 0 && closestUpEdge2 == 3) normalEdge = closestUpEdge + 1; else if ((closestUpEdge < closestUpEdge2) || (closestUpEdge == 3 && closestUpEdge2 == 0)) { normalEdge = closestUpEdge - 1; opposite = true; } else normalEdge = closestUpEdge + 1; if (RotationUpDirection < 0) opposite = !opposite; Vector3 upOffset; MyOrientedBoundingBox.GetNormalBetweenEdges(upAxis, closestUpEdge, normalEdge, out upOffset); Vector3 upOffsetWorld = Vector3.TransformNormal(upOffset, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawText3D(upCenter + upNormalForwWorld * 0.6f - upOffsetWorld * 0.01f, opposite ? upControlName1 : upControlName2, Color.White, textScale, false); //VRageRender.MyRenderProxy.DebugDrawText3D(upCenter2 + upNormalBackWorld * 0.6f - upOffsetWorld * 0.01f, opposite ? upControlName2 : upControlName1, Color.White, textScale, false); MyTransparentGeometry.AddBillboardOriented( "ArrowRed", Vector4.One, upCenter + upNormalForwWorld * 0.4f - upOffsetWorld * 0.01f, upNormalBackWorld, upDirection, 0.5f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowRed", Vector4.One, upCenter2 + upNormalBackWorld * 0.4f - upOffsetWorld * 0.01f, upNormalForwWorld, upDirection, 0.5f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(upCenter + upNormalForwWorld * 0.3f - upOffsetWorld * 0.01f, opposite ? upControlName2 : upControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(upCenter2 + upNormalBackWorld * 0.3f - upOffsetWorld * 0.01f, opposite ? upControlName1 : upControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } else //draw on edge { Vector3 normalUpBack, normalUpForw; MyOrientedBoundingBox.GetNormalBetweenEdges(upAxis, closestUpEdge, closestUpEdge + 1, out normalUpForw); MyOrientedBoundingBox.GetNormalBetweenEdges(upAxis, closestUpEdge, closestUpEdge - 1, out normalUpBack); Vector3D upCenter = (upStart + upEnd) * 0.5f; Vector3 upNormalForwWorld = Vector3.TransformNormal(normalUpForw, drawMatrix); Vector3 upNormalBackWorld = Vector3.TransformNormal(normalUpBack, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(upCenter, upCenter + upNormalForwWorld, Color.Green, Color.Green, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(upCenter, upCenter + upNormalBackWorld, Color.Green, Color.Green, false); MyTransparentGeometry.AddBillboardOriented( "ArrowRed", Vector4.One, upCenter + upNormalForwWorld * 0.3f - upNormalBackWorld * 0.01f, upNormalForwWorld, upDirection, 0.5f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowRed", Vector4.One, upCenter + upNormalBackWorld * 0.3f - upNormalForwWorld * 0.01f, upNormalBackWorld, upDirection, 0.5f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(upCenter + upNormalForwWorld * 0.6f - upNormalBackWorld * 0.01f, RotationUpDirection > 0 ? upControlName1 : upControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(upCenter + upNormalBackWorld * 0.6f - upNormalForwWorld * 0.01f, RotationUpDirection > 0 ? upControlName2 : upControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } } if (!(hideForwardAndUpArrows && RotationForwardAxis != 1)) { if (drawForwOnFaceCenter) { //VRageRender.MyRenderProxy.DebugDrawSphere((rightStart + rightEnd + rightStart2 + rightEnd2) * 0.25f, 0.2f, Vector3.Backward, 1.0f, false, false); Vector3D faceCenter = (rightStart + rightEnd + rightStart2 + rightEnd2) * 0.25f; MyTransparentGeometry.AddBillboardOriented( "ArrowLeftBlue", Vector4.One, faceCenter + RotationUpDirection * upDirection * 0.2f - RotationForwardDirection * forwDirection * 0.01f, RotationUpDirection * upDirection, -RotationRightDirection * rightDirection, 0.2f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowRightBlue", Vector4.One, faceCenter - RotationUpDirection * upDirection * 0.2f - RotationForwardDirection * forwDirection * 0.01f, -RotationUpDirection * upDirection, RotationRightDirection * rightDirection, 0.2f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(faceCenter + RotationUpDirection * upDirection * 0.2f - RotationForwardDirection * forwDirection * 0.01f, forwControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(faceCenter - RotationUpDirection * upDirection * 0.2f - RotationForwardDirection * forwDirection * 0.01f, forwControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_LEFT_AND_VERTICAL_CENTER, projectionId); } else if (drawForwOnFace) { //VRageRender.MyRenderProxy.DebugDrawLine3D(forwStart2, forwEnd2, Color.Blue, Color.Blue, false); Vector3 normalForwBack, normalForwForw; MyOrientedBoundingBox.GetNormalBetweenEdges(forwAxis, closestForwEdge, closestForwEdge2, out normalForwForw); Vector3D forwCenter = (forwStart + forwEnd) * 0.5f; Vector3 forwNormalForwWorld = Vector3.TransformNormal(normalForwForw, drawMatrix); MyOrientedBoundingBox.GetNormalBetweenEdges(forwAxis, closestForwEdge2, closestForwEdge, out normalForwBack); Vector3D forwCenter2 = (forwStart2 + forwEnd2) * 0.5f; Vector3 forwNormalBackWorld = Vector3.TransformNormal(normalForwBack, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(forwCenter, forwCenter + forwNormalForwWorld, Color.Blue, Color.Blue, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(forwCenter2, forwCenter2 + forwNormalBackWorld, Color.Blue, Color.Blue, false); int normalEdge = -1; bool opposite = false; if (closestForwEdge == 0 && closestForwEdge2 == 3) normalEdge = closestForwEdge + 1; else if ((closestForwEdge < closestForwEdge2) || (closestForwEdge == 3 && closestForwEdge2 == 0)) { normalEdge = closestForwEdge - 1; opposite = true; } else normalEdge = closestForwEdge + 1; if (RotationForwardDirection < 0) opposite = !opposite; Vector3 forwOffset; MyOrientedBoundingBox.GetNormalBetweenEdges(forwAxis, closestForwEdge, normalEdge, out forwOffset); Vector3 forwOffsetWorld = Vector3.TransformNormal(forwOffset, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawText3D(forwCenter + forwNormalForwWorld * 0.6f - forwOffsetWorld * 0.01f, opposite ? forwControlName2 : forwControlName1, Color.White, textScale, false); //VRageRender.MyRenderProxy.DebugDrawText3D(forwCenter2 + forwNormalBackWorld * 0.6f - forwOffsetWorld * 0.01f, opposite ? forwControlName1 : forwControlName2, Color.White, textScale, false); MyTransparentGeometry.AddBillboardOriented( "ArrowBlue", Vector4.One, forwCenter + forwNormalForwWorld * 0.4f - forwOffsetWorld * 0.01f, forwNormalBackWorld, forwDirection, 0.5f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowBlue", Vector4.One, forwCenter2 + forwNormalBackWorld * 0.4f - forwOffsetWorld * 0.01f, forwNormalForwWorld, forwDirection, 0.5f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(forwCenter + forwNormalForwWorld * 0.3f - forwOffsetWorld * 0.01f, opposite ? forwControlName1 : forwControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(forwCenter2 + forwNormalBackWorld * 0.3f - forwOffsetWorld * 0.01f, opposite ? forwControlName2 : forwControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } else //draw on edge { Vector3 normalForwBack, normalForwForw; MyOrientedBoundingBox.GetNormalBetweenEdges(forwAxis, closestForwEdge, closestForwEdge + 1, out normalForwForw); MyOrientedBoundingBox.GetNormalBetweenEdges(forwAxis, closestForwEdge, closestForwEdge - 1, out normalForwBack); Vector3D forwCenter = (forwStart + forwEnd) * 0.5f; Vector3 forwNormalForwWorld = Vector3.TransformNormal(normalForwForw, drawMatrix); Vector3 forwNormalBackWorld = Vector3.TransformNormal(normalForwBack, drawMatrix); //VRageRender.MyRenderProxy.DebugDrawLine3D(forwCenter, forwCenter + forwNormalForwWorld, Color.Blue, Color.Blue, false); //VRageRender.MyRenderProxy.DebugDrawLine3D(forwCenter, forwCenter + forwNormalBackWorld, Color.Blue, Color.Blue, false); MyTransparentGeometry.AddBillboardOriented( "ArrowBlue", Vector4.One, forwCenter + forwNormalForwWorld * 0.3f - forwNormalBackWorld * 0.01f, forwNormalForwWorld, forwDirection, 0.5f, 110, false, projectionId); MyTransparentGeometry.AddBillboardOriented( "ArrowBlue", Vector4.One, forwCenter + forwNormalBackWorld * 0.3f - forwNormalForwWorld * 0.01f, forwNormalBackWorld, forwDirection, 0.5f, 110, false, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(forwCenter + forwNormalForwWorld * 0.3f - forwNormalBackWorld * 0.01f, RotationForwardDirection < 0 ? forwControlName1 : forwControlName2, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); VRageRender.MyRenderProxy.DebugDrawText3D(forwCenter + forwNormalBackWorld * 0.3f - forwNormalForwWorld * 0.01f, RotationForwardDirection < 0 ? forwControlName2 : forwControlName1, Color.White, textScale, false, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER, projectionId); } } } }
// Draw OBB and highlight it white if selected private void DrawOBB(MyOrientedBoundingBoxD obb, Color color, float alpha, int identificationIndex) { if (identificationIndex == m_selected) { MyRenderProxy.DebugDrawOBB(obb, Color.White, 0.2f, false, false); } else { MyRenderProxy.DebugDrawOBB(obb, color, alpha, false, false); } }
/// <summary> /// Handles camera collisions with environment /// </summary> /// <param name="controlledEntity"></param> /// <param name="shakeActive"></param> /// <param name="headPosition"></param> /// <param name="headDirection"></param> /// <returns>False if no correct position was found</returns> private bool HandleIntersection(MyEntity controlledEntity, MyOrientedBoundingBoxD safeOBB, bool requireRaycast, bool shakeActive, Vector3D headPosition, Vector3 headDirection) { var line = new LineD(m_target, m_position); var safeOBBLine = new LineD(line.From, line.From + line.Direction * 2 * safeOBB.HalfExtent.Length()); Vector3D castStartSafe; { MyOrientedBoundingBoxD safeObbWithCollisionExtents = new MyOrientedBoundingBoxD(safeOBB.Center, safeOBB.HalfExtent + 2 * CAMERA_RADIUS, safeOBB.Orientation); double? safeIntersection = safeObbWithCollisionExtents.Intersects(ref safeOBBLine); if (!safeIntersection.HasValue) safeIntersection = safeOBB.HalfExtent.Length(); double safeDistance = safeIntersection.Value; castStartSafe = line.From + line.Direction * safeDistance; } { double? unsafeIntersection = safeOBB.Intersects(ref safeOBBLine); if (!requireRaycast && unsafeIntersection.HasValue) { var castStartUnsafe = line.From + line.Direction * unsafeIntersection.Value; var castEndUnsafe = castStartSafe + line.Direction; // short raycast, not causing problems with asteroids generating geometry Physics.MyPhysics.CastRay(castStartUnsafe, castEndUnsafe, m_raycastList, MyPhysics.DefaultCollisionLayer); if (!IsRaycastOK(m_raycastList)) { return false; } } } if (requireRaycast) { // short raycast, not causing problems with asteroids generating geometry Physics.MyPhysics.CastRay(line.From, castStartSafe + line.Direction, m_raycastList, MyPhysics.DefaultCollisionLayer); if (!IsRaycastOK(m_raycastList)) { return false; } } HkShape shape = new HkSphereShape(CAMERA_RADIUS); try { // small shape, not causing problems with asteroids generating geometry Physics.MyPhysics.GetPenetrationsShape(shape, ref castStartSafe, ref Quaternion.Identity, m_rigidList, 15); if (m_rigidList.Count > 0) { bool sameGrid = false; if (MySession.ControlledEntity != null && m_rigidList[0].Body != null) { sameGrid = m_rigidList[0].GetCollisionEntity() == MySession.ControlledEntity; } if (sameGrid) castStartSafe += line.Direction; } var shapeCastLine = new LineD(castStartSafe, m_position); uint steps = 1; uint stepIdx = 0; if (shapeCastLine.Length > SHAPE_CAST_STEP) { steps = (uint)Math.Ceiling(shapeCastLine.Length / SHAPE_CAST_STEP); if (steps >= SHAPE_CAST_MAX_STEP_COUNT) steps = SHAPE_CAST_MAX_STEP_COUNT - 1; stepIdx = m_updateCount % steps; m_lastShapeCastDistance[stepIdx] = float.PositiveInfinity; Vector3D step = shapeCastLine.Direction * (shapeCastLine.Length / steps); shapeCastLine = new LineD(castStartSafe + stepIdx * step, castStartSafe + (stepIdx + 1) * step); } if (false) { BoundingBoxD bbox = BoundingBoxD.CreateInvalid(); bbox.Include(new BoundingSphereD(shapeCastLine.From, CAMERA_RADIUS)); bbox.Include(new BoundingSphereD(shapeCastLine.To, CAMERA_RADIUS)); VRageRender.MyRenderProxy.DebugDrawAABB(bbox, Color.Crimson, 1f, 1f, true); } var matrix = MatrixD.CreateTranslation(shapeCastLine.From); HkContactPointData? cpd; if (controlledEntity.Physics != null && controlledEntity.Physics.CharacterProxy != null) cpd = MyPhysics.CastShapeReturnContactData(shapeCastLine.To, shape, ref matrix, controlledEntity.Physics.CharacterCollisionFilter, 0.0f); else cpd = MyPhysics.CastShapeReturnContactData(shapeCastLine.To, shape, ref matrix, HkGroupFilter.CalcFilterInfo(MyPhysics.DefaultCollisionLayer,0), 0.0f); if (cpd.HasValue) { var point = shapeCastLine.From + shapeCastLine.Direction * shapeCastLine.Length * cpd.Value.DistanceFraction; m_lastShapeCastDistance[stepIdx] = (float)(castStartSafe - point).Length(); } else { m_lastShapeCastDistance[stepIdx] = float.PositiveInfinity; } float? dist = null; for (int i = 0; i < steps; ++i) { if (m_lastShapeCastDistance[i] != float.PositiveInfinity) dist = Math.Min(m_lastShapeCastDistance[i], dist ?? float.PositiveInfinity); } if (dist.HasValue) { if (dist == 0.0f) { return false; } else { m_positionSafe = castStartSafe + shapeCastLine.Direction * dist.Value; } } else { m_positionSafe = m_position; } return true; } finally { shape.RemoveReference(); } }
public static unsafe void DisableItemsInObb(this MyEnvironmentSector sector, ref MyOrientedBoundingBoxD obb) { if (sector.DataView == null) return; obb.Center -= sector.SectorCenter; for (int sectorInd = 0; sectorInd < sector.DataView.LogicalSectors.Count; sectorInd++) { var logicalSector = sector.DataView.LogicalSectors[sectorInd]; var logicalItems = logicalSector.Items; var cnt = logicalItems.Count; fixed (ItemInfo* items = logicalItems.GetInternalArray()) for (int i = 0; i < cnt; ++i) { if (items[i].DefinitionIndex >= 0 && obb.Contains(ref items[i].Position)) logicalSector.EnableItem(i, false); } } }
protected override void DoDetection(bool useHead) { ProfilerShort.Begin("DoDetection"); if (Character == MySession.Static.ControlledEntity) MyHud.SelectedObjectHighlight.RemoveHighlight(); var head = Character.GetHeadMatrix(false); var headPos = head.Translation - (Vector3D)head.Forward * 0.3; // Move to center of head, we don't want eyes (in front of head) Vector3D from; Vector3D dir; if (!useHead) { //Ondrej version var cameraMatrix = MySector.MainCamera.WorldMatrix; dir = cameraMatrix.Forward; from = MyUtils.LinePlaneIntersection(headPos, (Vector3)dir, cameraMatrix.Translation, (Vector3)dir); } else { //Petr version dir = head.Forward; from = headPos; } Vector3D to = from + dir * MyConstants.DEFAULT_INTERACTIVE_DISTANCE; //EnableDetectorsInArea(from); GatherDetectorsInArea(from); float closestDetector = float.MaxValue; IMyEntity closestEntity = null; IMyUseObject closestInteractive = null; foreach(var entity in m_detectableEntities) { if (entity == Character) continue; var use = entity.Components.Get<MyUseObjectsComponentBase>() as MyUseObjectsComponent; if(use != null) { float detectorDistance; var interactive = use.RaycastDetectors(from, to, out detectorDistance); if(Math.Abs(detectorDistance) < Math.Abs(closestDetector)) { closestDetector = detectorDistance; closestEntity = entity; closestInteractive = interactive; } } //Floating object handling - give FO useobject component! var use2 = entity as IMyUseObject; if (use2 != null) { var m = use2.ActivationMatrix; var ray = new RayD(from, to - from); var obb = new MyOrientedBoundingBoxD(m); var dist = obb.Intersects(ref ray); if(dist.HasValue && Math.Abs(dist.Value) < Math.Abs(closestDetector)) { closestDetector = (float)dist.Value; closestEntity = entity; closestInteractive = use2; } } } m_detectableEntities.Clear(); //VRageRender.MyRenderProxy.DebugDrawLine3D(from, to, Color.Red, Color.Green, true); //VRageRender.MyRenderProxy.DebugDrawSphere(headPos, 0.05f, Color.Red.ToVector3(), 1.0f, false); StartPosition = from; MyPhysics.CastRay(from, to, m_hits, MyPhysics.CollisionLayers.FloatingObjectCollisionLayer); bool hasInteractive = false; int index = 0; while (index < m_hits.Count && (m_hits[index].HkHitInfo.Body == null || m_hits[index].HkHitInfo.GetHitEntity() == Character || m_hits[index].HkHitInfo.GetHitEntity() == null || m_hits[index].HkHitInfo.Body.HasProperty(HkCharacterRigidBody.MANIPULATED_OBJECT) || m_hits[index].HkHitInfo.Body.Layer == MyPhysics.CollisionLayers.VoxelLod1CollisionLayer)) // Skip invalid hits and self character { index++; } if (index < m_hits.Count && m_hits[index].HkHitInfo.HitFraction > closestDetector - 0.05f)//compensation { // TODO: Uncomment to enforce that character must face object by front to activate it //if (TestInteractionDirection(head.Forward, h.Position - GetPosition())) //return; HitPosition = from + dir * closestDetector; MyUseObjectsComponentBase useObject; if(closestEntity.Components.TryGet<MyUseObjectsComponentBase>(out useObject)) { var detectorPhysics = useObject.DetectorPhysics; HitMaterial = detectorPhysics.GetMaterialAt(HitPosition); HitBody = ((MyPhysicsBody)detectorPhysics).RigidBody; } else { HitMaterial = closestEntity.Physics.GetMaterialAt(HitPosition); HitBody = ((MyPhysicsBody)closestEntity.Physics).RigidBody; } DetectedEntity = closestEntity; var interactive = closestInteractive; if (UseObject != null && interactive != null && UseObject != interactive) { UseObject.OnSelectionLost(); } //if (interactive != null && interactive.SupportedActions != UseActionEnum.None && (Vector3D.Distance(from, (Vector3D)h.Position)) < interactive.InteractiveDistance && Character == MySession.Static.ControlledEntity) if (interactive != null && interactive.SupportedActions != UseActionEnum.None && closestDetector * MyConstants.DEFAULT_INTERACTIVE_DISTANCE < interactive.InteractiveDistance && Character == MySession.Static.ControlledEntity) { HandleInteractiveObject(interactive); UseObject = interactive; hasInteractive = true; } } if (!hasInteractive) { if (UseObject != null) { UseObject.OnSelectionLost(); } UseObject = null; } ProfilerShort.End(); }
public static void DebugDrawOBB(MyOrientedBoundingBoxD obb, Color color, float alpha, bool depthRead, bool smooth, bool persistent = false) { MatrixD obbMatrix = MatrixD.CreateFromQuaternion(obb.Orientation); obbMatrix.Right *= obb.HalfExtent.X*2; obbMatrix.Up *= obb.HalfExtent.Y*2; obbMatrix.Forward *= obb.HalfExtent.Z*2; obbMatrix.Translation = obb.Center; DebugDrawOBB(obbMatrix, color, alpha, depthRead, smooth, persistent: persistent); }
/// <summary> /// Gets the ground vertices and the target grid vertices /// </summary> public WorldVerticesInfo GetWorldVertices(float border, Vector3D originPosition, MyOrientedBoundingBoxD obb, List<BoundingBoxD> boundingBoxes, List<MyVoxelMap> trackedEntities) { ClearWorldVertices(); AddEntities(border, originPosition, obb, boundingBoxes, trackedEntities); AddGround(border, originPosition, obb, boundingBoxes); return m_worldVertices; }
public override void Draw() { base.Draw(); var pos = new Vector2(600, 100); foreach (var t in m_dbgComponents) { var has = SelectedEntity != null && SelectedEntity.Components.Contains(t); VRageRender.MyRenderProxy.DebugDrawText2D(pos, t.Name, has ? Color.Green : Color.White, 0.5f); pos.Y += 10; } pos = new Vector2(580, 100 + 10 * m_memoryA); VRageRender.MyRenderProxy.DebugDrawText2D(pos, ">>", Color.White, 0.5f); if (SelectedEntity != null) { var bbd = new BoundingBoxD(SelectedEntity.PositionComp.LocalAABB.Min, SelectedEntity.PositionComp.LocalAABB.Max); MyOrientedBoundingBoxD obb = new MyOrientedBoundingBoxD(bbd, SelectedEntity.WorldMatrix); //VRageRender.MyRenderProxy.DebugDrawOBB(obb, Color.White, 1, false, false); VRageRender.MyRenderProxy.DebugDrawAABB(SelectedEntity.PositionComp.WorldAABB, Color.White, 1, 1, false); } DrawBodyInfo(); //if (!MySandboxGame.Static.IsRunning) // return; //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(0.1f, 0.1f), "Destruction: " + (MyPerGameSettings.Destruction ? "ON" : "OFF"), Color.Red, 1); //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(200f, 5f), "(Ctrl+Shift+D)", Color.Red, 0.65f); //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(0.3f, 20f), "Strenght: " + STRENGHT, Color.Red, 1); //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(0.1f, 40f), "Fracture: " + (FRACTURE ? "ON" : "OFF"), Color.Red, 1); //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(160f, 45f), "(Ctrl+Shift+F)", Color.Red, 0.65f); //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(0.1f, 60f), "Integrity: " + (MyFakes.DESTRUCTION_STRUCTURAL_INTEGRITY ? "ON" : "OFF"), Color.Red, 1); //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(160f, 65f), "(Ctrl+I)", Color.Red, 0.65f); //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(0.1f, 80f), "Position: " + POSITION, Color.Red, 1); //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(0.1f, 100f), "Split: " + (GRID_SPLIT ? "ON" : "OFF"), Color.Red, 1); //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(0.1f, 120f), "AConn: " + (!ManualConnect ? "ON" : "OFF"), Color.Red, 1); //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(0.1f, 140f), "Hammer: " + (DestructionTool ? "ON" : "OFF"), Color.Red, 1); //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(0.1f, 0.1f), "MassMultiplier " + MassMultiplier, Color.Red, 1); //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(0.3f, 20f), ApplyMassMultiplier ? "ON" : "OFF", Color.Red, 1); //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(0.3f, 40f), "Num1, N, B, ;, '", Color.Red, 1); }
/// <summary> /// Adds the vertices from the grid blocks that are inside the given OBB /// </summary> /// <param name="grid"></param> /// <param name="obb"></param> /// <param name="vertices"></param> private void AddGridVerticesInsideOBB(MyCubeGrid grid, MyOrientedBoundingBoxD obb) { var aabb = obb.GetAABB(); var gridGroup = MyCubeGridGroups.Static.Logical.GetGroup(grid); foreach (var node in gridGroup.Nodes) { var cubeGrid = (MyCubeGrid)node.NodeData; m_rdPathfinding.AddToTrackedGrids(cubeGrid); var worldMatrix = cubeGrid.WorldMatrix; worldMatrix.Translation -= m_center; var toRDWorld = MatrixD.Transform(worldMatrix, rdWorldQuaternion); if (MyPerGameSettings.Game == GameEnum.SE_GAME) { var box = aabb.TransformFast(cubeGrid.PositionComp.WorldMatrixNormalizedInv); Vector3I start = new Vector3I((int)Math.Round(box.Min.X), (int)Math.Round(box.Min.Y), (int)Math.Round(box.Min.Z)); Vector3I end = new Vector3I((int)Math.Round(box.Max.X), (int)Math.Round(box.Max.Y), (int)Math.Round(box.Max.Z)); start = Vector3I.Min(start, end); end = Vector3I.Max(start, end); ProfilerShort.Begin("GetShapesInInterval"); if (cubeGrid.Physics != null) cubeGrid.Physics.Shape.GetShapesInInterval(start, end, m_tmpShapes); ProfilerShort.End(); ProfilerShort.Begin("AddVertices"); foreach (var shape in m_tmpShapes) AddPhysicalShape(shape, toRDWorld); m_tmpShapes.Clear(); ProfilerShort.End(); } } }
/// <summary> /// Handles camera collisions with environment /// </summary> /// <returns>False if no correct position was found</returns> private void HandleIntersection(MyEntity controlledEntity) { Debug.Assert(controlledEntity != null); MyEntity parentEntity = controlledEntity.GetTopMostParent() ?? controlledEntity; var parentEntityAsCubeGrid = parentEntity as MyCubeGrid; if (parentEntityAsCubeGrid != null && parentEntityAsCubeGrid.IsStatic) parentEntity = controlledEntity; // cancel previous assignment, topmost parent is a station, we need smaller bounding box // line from target to eye LineD line = new LineD(m_target, m_position); // oriented bb of the entity MyOrientedBoundingBoxD safeObb = GetEntitySafeOBB(parentEntity); // oriented bb of the entity + camera radius MyOrientedBoundingBoxD safeObbWithCollisionExtents = new MyOrientedBoundingBoxD(safeObb.Center, safeObb.HalfExtent + (controlledEntity.Parent == null ? 0.5 : 2.0) * CAMERA_RADIUS, safeObb.Orientation); // start = target, end = eye // find safe start... LineD safeOBBLine = new LineD(line.From + line.Direction * 2 * safeObb.HalfExtent.Length(), line.From); double? safeIntersection = safeObbWithCollisionExtents.Intersects(ref safeOBBLine); Vector3D castStartSafe = safeIntersection != null ? (safeOBBLine.From + safeOBBLine.Direction * safeIntersection.Value) : m_target; if (controlledEntity.Parent != null && safeIntersection != null) { MatrixD shapeCastStart = MatrixD.CreateTranslation(castStartSafe); HkShape hkSphere = new HkSphereShape(CAMERA_RADIUS * 2); var hitInfo = MyPhysics.CastShapeReturnContactBodyData(m_target, hkSphere, ref shapeCastStart, 0, 0); //VRageRender.MyRenderProxy.DebugDrawCapsule(castStartSafe, m_target, CAMERA_RADIUS * 2, Color.Orange, false); MyEntity hitEntity = hitInfo.HasValue ? hitInfo.Value.HkHitInfo.GetHitEntity() as MyEntity : null; MyEntity entity = controlledEntity; var hitEntityWeldingGroup = hitEntity != null ? MyWeldingGroups.Static.GetGroup(hitEntity) : null; bool weldingGroupEquals = false; while (entity != null && !weldingGroupEquals) { if (hitEntityWeldingGroup == MyWeldingGroups.Static.GetGroup(entity)) weldingGroupEquals = true; entity = entity.Parent; } if (hitInfo.HasValue && hitEntityWeldingGroup != null && weldingGroupEquals) { castStartSafe = castStartSafe + hitInfo.Value.HkHitInfo.HitFraction * (m_target - castStartSafe); } else { safeObb = GetEntitySafeOBB(controlledEntity); safeObbWithCollisionExtents = new MyOrientedBoundingBoxD(safeObb.Center, safeObb.HalfExtent + 0.5f * CAMERA_RADIUS, safeObb.Orientation); safeIntersection = safeObbWithCollisionExtents.Intersects(ref safeOBBLine); castStartSafe = safeIntersection != null ? (safeOBBLine.From + safeOBBLine.Direction * safeIntersection.Value) : m_target; } hkSphere.RemoveReference(); } // raycast against occluders Vector3D safePositionCandidate; //double lastSafeMinimumDistance = m_safeMinimumDistance; m_safeMinimumDistance = controlledEntity is MyCharacter ? 0 : (castStartSafe - m_target).Length(); // store current safe minimum dist m_safeMinimumDistance = Math.Max(m_safeMinimumDistance, MIN_VIEWER_DISTANCE); //if (lastSafeMinimumDistance + 30.0f < m_safeMinimumDistance) //{ // castStartSafe = m_target + (castStartSafe - m_target) / m_safeMinimumDistance * lastSafeMinimumDistance; // m_safeMinimumDistance = lastSafeMinimumDistance; //} Vector3D raycastOrigin = (controlledEntity is MyCharacter) ? m_target : castStartSafe; MyCameraRaycastResult raycastResult = RaycastOccludingObjects(controlledEntity, ref raycastOrigin, ref m_position, ref castStartSafe, out safePositionCandidate); // visual debugging :) if (m_debugDraw) { VRageRender.MyRenderProxy.DebugDrawOBB(safeObb, Color.Red, 0.1f, false, true); VRageRender.MyRenderProxy.DebugDrawOBB(safeObbWithCollisionExtents, Color.Yellow, 0.0f, false, true); VRageRender.MyRenderProxy.DebugDrawArrow3D(safeOBBLine.From, safeOBBLine.To, Color.White, Color.Purple, false); VRageRender.MyRenderProxy.DebugDrawArrow3D(safeOBBLine.From, castStartSafe, Color.White, Color.Red, false); VRageRender.MyRenderProxy.DebugDrawArrow3D(castStartSafe, m_position, Color.White, Color.Orange, false); VRageRender.MyRenderProxy.DebugDrawSphere(castStartSafe, 0.2f, Color.Green, 1.0f, false, true); VRageRender.MyRenderProxy.DebugDrawSphere(safePositionCandidate, 1.0f, Color.LightPink, 1, false); } switch (raycastResult) { case MyCameraRaycastResult.Ok: case MyCameraRaycastResult.FoundOccluder: m_positionCurrentIsSafe = true; { double distFromCandidateToTarget = (safePositionCandidate - m_target).Length(); if (m_disableSpringThisFrame) { m_lastRaycastDist = (float) distFromCandidateToTarget; } if (!m_disableSpringThisFrame && ((distFromCandidateToTarget > m_lastRaycastDist + CAMERA_RADIUS && distFromCandidateToTarget > m_safeMinimumDistance) || raycastResult == MyCameraRaycastResult.Ok)) { // now we need it from the other side double newDist = (safePositionCandidate - m_position).Length(); // new safe position is further from target => change over time (zoom out) if (m_positionSafeZoomingOutTimeout <= 0) { float distDiffZoomSpeed = 1 - MathHelper.Clamp((float) Math.Abs(m_lastRaycastDist - newDist), 0.0f, 1.0f - MyEngineConstants.UPDATE_STEP_SIZE_IN_SECONDS); m_positionSafeZoomingOutSpeed += distDiffZoomSpeed; m_positionSafeZoomingOutSpeed = MathHelper.Clamp(m_positionSafeZoomingOutSpeed, 0.0f, 1.0f); Vector3D targetToPosSafe = m_positionSafe - m_target; double lenTargetToPosSafe = targetToPosSafe.Length(); Vector3D rotatedPositionSafe = m_target + Vector3D.Normalize(safePositionCandidate - m_target) * lenTargetToPosSafe; m_positionSafe = Vector3D.Lerp(rotatedPositionSafe, safePositionCandidate, m_positionSafeZoomingOutSpeed); } else { m_positionSafeZoomingOutTimeout -= MyEngineConstants.UPDATE_STEP_SIZE_IN_MILLISECONDS; Vector3D targetToPosSafe = m_positionSafe - m_target; double lenTargetToPosSafe = targetToPosSafe.Length(); m_positionSafe = m_target + Vector3D.Normalize(safePositionCandidate - m_target) * lenTargetToPosSafe; } } else { // new safe position is closer or closer than safe distance => instant change m_positionSafeZoomingOutSpeed = 0.0f; // set zooming out speed to zero for next time m_positionSafeZoomingOutTimeout = 0;// controlledEntity.Parent != null ? m_positionSafeZoomingOutDefaultTimeoutMs : 0; m_positionSafe = safePositionCandidate; m_disableSpringThisFrame = true; m_positionCurrentIsSafe = distFromCandidateToTarget >= m_safeMinimumDistance; } } break; //case MyCameraRaycastResult.FoundOccluderNoSpace: default: m_positionSafeZoomingOutSpeed = 1.0f; // we're in first person, change instantly to third if possible m_positionCurrentIsSafe = false; break; } m_lastRaycastDist = (float)(m_positionSafe - m_position).Length(); if (m_debugDraw) { VRageRender.MyRenderProxy.DebugDrawSphere(m_positionSafe, 0.225f, Color.Purple, 1, false); VRageRender.MyRenderProxy.DebugDrawSphere(safePositionCandidate, 0.2f, Color.Azure, 1, false); } }
private unsafe Vector3* GetMiddleOBBLocalPoints(MyOrientedBoundingBoxD obb, ref Vector3* points) { Vector3 xDiff = obb.Orientation.Right * (float)obb.HalfExtent.X; Vector3 zDiff = obb.Orientation.Forward * (float)obb.HalfExtent.Z; Vector3 localPosition = obb.Center - m_planet.PositionComp.GetPosition(); points[0] = localPosition - xDiff - zDiff; points[1] = localPosition + xDiff - zDiff; points[2] = localPosition + xDiff + zDiff; points[3] = localPosition - xDiff + zDiff; return points; }
private static MyOrientedBoundingBoxD GetEntitySafeOBB(MyEntity controlledEntity) { var localAABB = controlledEntity.PositionComp.LocalAABB; Vector3D center = Vector3D.Transform((Vector3D) localAABB.Center, controlledEntity.WorldMatrix); var safeOBB = new MyOrientedBoundingBoxD(center, localAABB.HalfExtents, Quaternion.CreateFromRotationMatrix(controlledEntity.WorldMatrix.GetOrientation())); return safeOBB; }
private void AddGround(float border, Vector3D originPosition, MyOrientedBoundingBoxD obb, List<BoundingBoxD> bbList) { ProfilerShort.Begin("Predict terrain - SetTerrainLimits()"); bool hasTerrain = SetTerrainLimits(ref obb); ProfilerShort.End(); if (!hasTerrain) return; AddVoxelMesh(m_planet, m_planet.Storage, m_meshCache, border, originPosition, obb, bbList); }
/// <summary> /// Fills a "horizontal" line of OBBs /// </summary> private void FillOBBHorizontalLine(MyOrientedBoundingBoxD lineCenterOBB, Vector2I currentIndex, double angle) { m_obbs[currentIndex.Y][currentIndex.X] = lineCenterOBB; for (int i = 0; i < OBBsPerLine; i++) if (i != currentIndex.X) { var ob = CreateOBB(NewTransformedPoint(lineCenterOBB.Center, lineCenterOBB.Orientation.Right, (float)(angle * (i - m_middleCoord))), lineCenterOBB.Orientation.Right); m_obbs[currentIndex.Y][i] = ob; } }
private bool QueryEmptyOrFull(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { ////return false; var bb = new BoundingBox(new Vector3(minX, minY, minZ), new Vector3(maxX, maxY, maxZ)); if (bb.Volume() < 100) return false; //bb.Translate(m_voxelMap.StorageMin); var result = m_voxelMap.Storage.Intersect(ref bb, false) != ContainmentType.Intersects; { var bbd = new BoundingBoxD(new Vector3(minX, minY, minZ) * 8, new Vector3(maxX, maxY, maxZ) * 8); bbd.Transform(Entity.WorldMatrix); var obb = new MyOrientedBoundingBoxD(bbd, Entity.WorldMatrix); MyRenderProxy.DebugDrawAABB(bbd, result ? Color.Green : Color.Red, 1, 1, false); } return result; }
public override void Handle() { var tmpEntities = new HashSet <IMyEntity>(); MyAPIGateway.Entities.GetEntities(tmpEntities); if (tmpEntities.Count == 0) { Logging.Instance.WriteLine("Failed to get list of entities in ShipyardDetection."); return; } //copy the list of entities because concurrency IMyEntity[] entities = tmpEntities.ToArray(); //run through our current list of shipyards and make sure they're still valid var itemsToRemove = new HashSet <ShipyardItem>(); var firstCheckBlock = Profiler.Start(FullName, nameof(Handle), "First Check"); foreach (ShipyardItem item in ShipyardsList) { if (!AreToolsConnected(item.Tools)) { Logging.Instance.WriteLine("remove item tools " + item.Tools.Length); item.Disable(); itemsToRemove.Add(item); foreach (var tool in item.Tools) { Communication.SendCustomInfo(tool.EntityId, "Invalid Shipyard: All tools must be on the same conveyor network!"); } continue; } if (item.Tools.Any(x => x.Closed || x.MarkedForClose)) { Logging.Instance.WriteLine("remove item closed tools " + item.Tools.Length); item.Disable(); itemsToRemove.Add(item); continue; } if (!entities.Contains(item.YardEntity) || item.YardEntity.Closed || item.YardEntity.MarkedForClose) { Logging.Instance.WriteLine("remove item entity"); item.Disable(); itemsToRemove.Add(item); continue; } using (Profiler.Start(FullName, nameof(Handle), "Physics Check")) { if (item.YardEntity.Physics == null || item.StaticYard && (!item.YardEntity.Physics.IsStatic || !((IMyCubeGrid)item.YardEntity).IsInVoxels())) { Logging.Instance.WriteLine("remove item physics"); itemsToRemove.Add(item); item.Disable(); foreach (var tool in item.Tools) { Communication.SendCustomInfo(tool.EntityId, "Invalid Shipyard: Shipyard must be anchored to voxels!"); } continue; } } if (item.Tools.Any(t => ((IMyTerminalBlock)t).CustomInfo.Contains("Invalid Shipyard"))) { foreach (var tool in item.Tools) { Communication.SendCustomInfo(tool.EntityId, string.Empty); } } } firstCheckBlock.End(); foreach (ShipyardItem item in itemsToRemove) { item.YardType = ShipyardType.Invalid; Communication.SendYardState(item); ShipyardsList.Remove(item); } foreach (IMyEntity entity in entities) { _corners.Clear(); var grid = entity as IMyCubeGrid; if (grid?.Physics == null || grid.Closed || grid.MarkedForClose) { continue; } if (ShipyardsList.Any(x => x.EntityId == entity.EntityId)) { continue; } var gridBlocks = new List <IMySlimBlock>(); grid.GetBlocks(gridBlocks); foreach (IMySlimBlock slimBlock in gridBlocks.ToArray()) { var collector = slimBlock.FatBlock as IMyCollector; if (collector == null) { continue; } if (collector.BlockDefinition.SubtypeId.StartsWith("ShipyardCorner")) { _corners.Add(slimBlock.FatBlock); } } if (_corners.Count != 8) { foreach (var tool in _corners) { Communication.SendCustomInfo(tool.EntityId, $"Invalid Shipyard: Must be 8 corner blocks, there are {_corners.Count} on this grid!"); } continue; } if (_corners.Any(c => c.BlockDefinition.SubtypeId != _corners[0].BlockDefinition.SubtypeId)) { foreach (var tool in _corners) { Communication.SendCustomInfo(tool.EntityId, $"Invalid Shipyard: All 8 corner blocks must be the same type!"); } continue; } using (Profiler.Start(FullName, nameof(Handle), "Static Check")) { if (_corners[0].BlockDefinition.SubtypeId == "ShipyardCorner_Large" && !ShipyardCore.Debug) { if (!grid.IsStatic || !grid.IsInVoxels()) { Logging.Instance.WriteDebug($"Yard {grid.EntityId} failed: Static check"); foreach (var tool in _corners) { Communication.SendCustomInfo(tool.EntityId, "Invalid Shipyard: Shipyard must be anchored to voxels!"); } continue; } } } if (!IsYardValid(entity, _corners)) { continue; } //add an offset of 2.5m because the corner points are at the center of a 3^3 block, and the yard will be 2.5m short in all dimensions MyOrientedBoundingBoxD testBox = MathUtility.CreateOrientedBoundingBox((IMyCubeGrid)entity, _corners.Select(x => x.GetPosition()).ToList(), 2.5); Logging.Instance.WriteLine("Found yard"); var item = new ShipyardItem( testBox, _corners.ToArray(), ShipyardType.Disabled, entity); item.Settings = ShipyardSettings.Instance.GetYardSettings(item.EntityId); foreach (IMyCubeBlock tool in _corners) { item.BlocksToProcess.Add(tool.EntityId, new BlockTarget[3]); } ShipyardsList.Add(item); Communication.SendNewYard(item); foreach (var tool in item.Tools) { Communication.SendCustomInfo(tool.EntityId, ""); } } Communication.SendYardCount(); }