public void Start(MyModel model, MyLine line, IntersectionFlags flags = IntersectionFlags.DIRECT_TRIANGLES) { result = null; m_model = model; m_line = line; m_flags = flags; }
// Calculates intersection of line with any triangleVertexes in this model instance. Closest intersection and intersected triangleVertexes will be returned. internal override bool GetIntersectionWithLine(ref LineD line, out MyIntersectionResultLineTriangleEx? t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { t = null; return false; //Matrix invWorld = Matrix.Invert(WorldMatrix); //Vector3 from = Vector3.Transform(line.From, invWorld); //Vector3 to = Vector3.Transform(line.To, invWorld); //Line lineLocal = new Line(from, to); //bool res = base.GetIntersectionWithLine(ref line, out t, flags); //if (res) //{ // var definition = MyDefinitionManager.Static.GetCubeBlockDefinition(new MyDefinitionId(MyObjectBuilderTypeEnum.Ladder)); // if (definition.ExcludedAreaForCamera != null) // { // foreach (var b in definition.ExcludedAreaForCamera) // { // if (b.Contains(t.Value.IntersectionPointInObjectSpace) == ContainmentType.Contains) // { // t = null; // return false; // } // } // } //} //return res; }
public Sandbox.Common.MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(IMyEntity physObject, ref LineD line, ref MatrixD customInvMatrix, IntersectionFlags flags) { LineD lineInModelSpace = new LineD(Vector3D.Transform(line.From, ref customInvMatrix), Vector3D.Transform(line.To, ref customInvMatrix)); MyIntersectionResultLineTriangleEx? ret = m_rootNode.GetIntersectionWithLine(physObject, m_model, ref lineInModelSpace, null, flags); return ret; }
public MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(MyEntity physObject, ref MyLine line, ref Matrix customInvMatrix, IntersectionFlags flags) { MyLine lineInModelSpace = new MyLine(MyUtils.GetTransform(line.From, ref customInvMatrix), MyUtils.GetTransform(line.To, ref customInvMatrix), true); MyIntersectionResultLineTriangleEx? ret = m_rootNode.GetIntersectionWithLine(physObject, m_model, ref lineInModelSpace, null, flags); return ret; }
// Calculates intersection of line with any triangleVertexes in this model. Closest intersection and intersected triangleVertexes will be returned. // This method is fast, it uses octree. public Sandbox.Common.MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(IMyEntity physObject, ref LineD line, IntersectionFlags flags) { BoundingSphereD vol = physObject.WorldVolume; // Check if line intersects phys object's current bounding sphere, and if not, return 'no intersection' if (MyUtils.IsLineIntersectingBoundingSphere(ref line, ref vol) == false) return null; // Transform line into 'model instance' local/object space. Bounding box of a line is needed!! MatrixD worldInv = physObject.GetWorldMatrixNormalizedInv(); return GetIntersectionWithLine(physObject, ref line, ref worldInv, flags); }
// Difference between GetIntersectionWithLine and GetIntersectionWithLineRecursive is that the later doesn't calculate // final result, but is better suited for recursive nature of octree. Don't call GetIntersectionWithLineRecursive() from // the outisde of this class, it's private method. public MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(MyEntity physObject, MyModel model, ref MyLine line, float? minDistanceUntilNow, IntersectionFlags flags) { MyIntersectionResultLineTriangle? foundTriangle = GetIntersectionWithLineRecursive(model, ref line, minDistanceUntilNow); if (foundTriangle != null) { return new MyIntersectionResultLineTriangleEx(foundTriangle.Value, physObject, ref line); } else { return null; } }
public MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(MyEntity physObject, ref MyLine line, ref Matrix customInvMatrix, IntersectionFlags flags) { MyLine lineInModelSpace = new MyLine(MyUtils.GetTransform(line.From, ref customInvMatrix), MyUtils.GetTransform(line.To, ref customInvMatrix), true); //MyIntersectionResultLineTriangle? result = null; m_result.Start(m_model, lineInModelSpace, flags); var dir = new IndexedVector3(lineInModelSpace.Direction); var from = new IndexedVector3(lineInModelSpace.From); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("m_bvh.RayQueryClosest()"); m_bvh.RayQueryClosest(ref dir, ref from, m_result.ProcessTriangleHandler); MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock(); if (m_result.Result.HasValue) { return new MyIntersectionResultLineTriangleEx(m_result.Result.Value, physObject, ref lineInModelSpace); } else { return null; } }
// Calculates intersection of line with any triangleVertexes in this model instance. Closest intersection and intersected triangleVertexes will be returned. internal override bool GetIntersectionWithLine(ref LineD line, out MyIntersectionResultLineTriangleEx?t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { t = null; return(false); }
public void GetTrianglesIntersectingLine(IMyEntity entity, ref LineD line, IntersectionFlags flags, List<MyIntersectionResultLineTriangleEx> result) { MatrixD worldInv = entity.PositionComp.WorldMatrixNormalizedInv; GetTrianglesIntersectingLine(entity, ref line, ref worldInv, flags, result); }
/// <summary> /// Calculates intersected block with all models replaced by final models. Useful for construction/deconstruction when models are made from wooden construction. /// </summary> public bool GetIntersectionWithLine_FullyBuiltProgressModels(ref LineD line, out VRage.Game.Models.MyIntersectionResultLineTriangleEx? t, out ushort blockId, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES, bool checkZFight = false, bool ignoreGenerated = false) { t = null; blockId = 0; double distanceSquaredInCompound = double.MaxValue; bool foundIntersection = false; foreach (var blockPair in m_mapIdToBlock) { MySlimBlock cmpSlimBlock = blockPair.Value; if (ignoreGenerated && cmpSlimBlock.BlockDefinition.IsGeneratedBlock) continue; MyModel collisionModel = MyModels.GetModelOnlyData(cmpSlimBlock.BlockDefinition.Model); if (collisionModel != null) { VRage.Game.Models.MyIntersectionResultLineTriangleEx? intersectionTriResult = collisionModel.GetTrianglePruningStructure().GetIntersectionWithLine( cmpSlimBlock.FatBlock, ref line, flags); if (intersectionTriResult != null) { Vector3D startToIntersection = intersectionTriResult.Value.IntersectionPointInWorldSpace - line.From; double instrDistanceSq = startToIntersection.LengthSquared(); if (instrDistanceSq < distanceSquaredInCompound) { if (checkZFight && distanceSquaredInCompound < instrDistanceSq + 0.001f) continue; distanceSquaredInCompound = instrDistanceSq; t = intersectionTriResult; blockId = blockPair.Key; foundIntersection = true; } } } } return foundIntersection; }
public void GetTrianglesIntersectingLine(IMyEntity entity, ref LineD line, IntersectionFlags flags, List <MyIntersectionResultLineTriangleEx> result) { MatrixD worldInv = entity.PositionComp.WorldMatrixNormalizedInv; GetTrianglesIntersectingLine(entity, ref line, ref worldInv, flags, result); }
public override bool GetIntersectionWithLine(ref LineD worldLine, out Vector3D? v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { MyIntersectionResultLineTriangleEx? result; GetIntersectionWithLine(ref worldLine, out result); v = null; if (result != null) { v = result.Value.IntersectionPointInWorldSpace; return true; } return false; }
public override bool GetIntersectionWithLine(ref MyLine line, out Vector3?v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { v = null; Ray ray = new Ray(line.From, line.Direction); float?ds = null; if (EntityDetectorType == MyEntityDetectorType.Box) { ds = ray.Intersects(this.WorldAABB); } else if (EntityDetectorType == MyEntityDetectorType.Sphere) { ds = ray.Intersects(new BoundingSphere(WorldMatrix.Translation, m_radius)); } if (ds == null) { return(false); } v = line.From + line.Direction * ds; return(true); }
// Calculates intersection of line with any triangleVertexes in this model instance. Closest intersection and intersected triangleVertexes will be returned. public override bool GetIntersectionWithLine(ref LineD line, out VRage.Game.Models.MyIntersectionResultLineTriangleEx?t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { t = null; return(false); }
public bool Intersect(ref Line localLine, out VRage.Game.Models.MyIntersectionResultLineTriangle result, IntersectionFlags flags) { MyPrecalcComponent.AssertUpdateThread(); ProfilerShort.Begin("VoxelMap.LineIntersection AABB sweep"); m_sweepResultCache.Clear(); MyGridIntersection.Calculate( m_sweepResultCache, (int)MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES, localLine.From, localLine.To, new Vector3I(0, 0, 0), m_cellsCount - 1 ); ProfilerShort.End(); ProfilerShort.Begin("VoxelMap.LineIntersection test AABBs"); float? minDistanceUntilNow = null; BoundingBox cellBoundingBox; MyCellCoord cell = new MyCellCoord(); VRage.Game.Models.MyIntersectionResultLineTriangle?tmpResult = null; for (int index = 0; index < m_sweepResultCache.Count; index++) { cell.CoordInLod = m_sweepResultCache[index]; MyVoxelCoordSystems.GeometryCellCoordToLocalAABB(ref cell.CoordInLod, out cellBoundingBox); float?distanceToBoundingBox = MyUtils.GetLineBoundingBoxIntersection(ref localLine, ref cellBoundingBox); // Sweep results are sorted; when we get far enough, make an early exit const float earlyOutDistance = 1.948557f * MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES; // = sqrt(3) * 9/8 * cell_side if (minDistanceUntilNow != null && distanceToBoundingBox != null && minDistanceUntilNow + earlyOutDistance < distanceToBoundingBox.Value) { break; } // Get cell from cache. If not there, precalc it and store in the cache. // If null is returned, we know that cell doesn't contain any triangleVertexes so we don't need to do intersections. CellData cachedDataCell = GetCell(ref cell); if (cachedDataCell == null || cachedDataCell.VoxelTrianglesCount == 0) { continue; } GetCellLineIntersectionOctree(ref tmpResult, ref localLine, ref minDistanceUntilNow, cachedDataCell, flags); } ProfilerShort.End(); result = tmpResult ?? default(VRage.Game.Models.MyIntersectionResultLineTriangle); return(tmpResult.HasValue); }
public override bool GetIntersectionWithLine(ref MyLine line, out Vector3?v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { v = null; BoundingBox box = BoundingBox.CreateFromSphere(new BoundingSphere(GetPosition(), m_selectionBox.Size().X)); float? dt = MyUtils.GetLineBoundingBoxIntersection(ref line, ref box); if (dt == null) { return(false); } v = line.From + line.Direction * dt; return(true); }
// Method finds intersection with line and any voxel triangleVertexes in this voxel map. Closes intersection is returned. internal override bool GetIntersectionWithLine(ref Line worldLine, out MyIntersectionResultLineTriangleEx?t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { t = null; float intersectionDistance; if (!m_worldAABB.Intersects(worldLine, out intersectionDistance)) { return(false); } Profiler.Begin("VoxelMap.LineIntersection"); try { return(Geometry.Intersect(ref worldLine, out t, flags)); } finally { Profiler.End(); } }
public override bool GetIntersectionWithLine(ref MyLine line, out MyIntersectionResultLineTriangleEx?t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { t = null; foreach (MyPrefabBase prefab in m_prefabs) { MyEntity entity = prefab as MyEntity; MyIntersectionResultLineTriangleEx?prefabIntersectionResult; entity.GetIntersectionWithLine(ref line, out prefabIntersectionResult); t = MyIntersectionResultLineTriangleEx.GetCloserIntersection(ref t, ref prefabIntersectionResult); } return(t != null); }
public VRage.Game.Models.MyIntersectionResultLineTriangleEx?GetIntersectionWithLine(IMyEntity entity, ref LineD line, IntersectionFlags flags) { BoundingSphereD vol = entity.PositionComp.WorldVolume; // Check if line intersects phys object's current bounding sphere, and if not, return 'no intersection' if (MyUtils.IsLineIntersectingBoundingSphere(ref line, ref vol) == false) { return(null); } // Transform line into 'model instance' local/object space. Bounding box of a line is needed!! MatrixD worldInv = entity.PositionComp.WorldMatrixInvScaled; return(GetIntersectionWithLine(entity, ref line, ref worldInv, flags)); }
public void GetTrianglesIntersectingLine(IMyEntity entity, ref LineD line, ref MatrixD customInvMatrix, IntersectionFlags flags, List <MyIntersectionResultLineTriangleEx> result) { LineD lineInModelSpace = new LineD(Vector3D.Transform(line.From, ref customInvMatrix), Vector3D.Transform(line.To, ref customInvMatrix)); m_resultAll.Start(m_model, lineInModelSpace, flags); var dir = lineInModelSpace.Direction.ToBullet(); var from = lineInModelSpace.From.ToBullet(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("m_bvh.RayQueryClosest()"); m_bvh.RayQuery(ref dir, ref from, m_resultAll.ProcessTriangleHandler); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); m_resultAll.End(); foreach (var intersection in m_resultAll.Result) { result.Add(new VRage.Game.Models.MyIntersectionResultLineTriangleEx(intersection, entity, ref lineInModelSpace)); } }
public VRage.Game.Models.MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(IMyEntity entity, ref LineD line, IntersectionFlags flags) { BoundingSphereD vol = entity.PositionComp.WorldVolume; // Check if line intersects phys object's current bounding sphere, and if not, return 'no intersection' if (MyUtils.IsLineIntersectingBoundingSphere(ref line, ref vol) == false) return null; // Transform line into 'model instance' local/object space. Bounding box of a line is needed!! MatrixD worldInv = entity.PositionComp.WorldMatrixInvScaled; return GetIntersectionWithLine(entity, ref line, ref worldInv, flags); }
/* * protected override void Explode() * { * MyExplosion newExplosion = MyExplosions.AddExplosion(); * if (newExplosion != null) * { * BoundingSphere explosionSphere = WorldVolumeHr; * explosionSphere.Radius *= m_config.ExplosionRadiusMultiplier; * MyVoxelMap voxelMap = MyVoxelMaps.GetOverlappingWithSphere(ref explosionSphere); * MyExplosionDebrisModel.CreateExplosionDebris(ref explosionSphere, MyGroupMask.Empty, this, voxelMap); * newExplosion.Start(0, MyPrefabConstants.VOLUME_DAMAGE_MULTIPLIER * m_config.ExplosionDamageMultiplier * WorldVolumeHr.Radius, 0, m_config.ExplosionType, explosionSphere, MyExplosionsConstants.EXPLOSION_LIFESPAN); * } * } */ public override bool GetIntersectionWithLine(ref MyLine line, out MyIntersectionResultLineTriangleEx?t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { return(m_gun.GetIntersectionWithLine(ref line, out t)); }
// Difference between GetIntersectionWithLine and GetIntersectionWithLineRecursive is that the later doesn't calculate // final result, but is better suited for recursive nature of octree. Don't call GetIntersectionWithLineRecursive() from // the outisde of this class, it's private method. public MyIntersectionResultLineTriangleEx?GetIntersectionWithLine(IMyEntity physObject, MyModel model, ref LineD line, double?minDistanceUntilNow, IntersectionFlags flags) { MyIntersectionResultLineTriangle?foundTriangle = GetIntersectionWithLineRecursive(model, ref line, minDistanceUntilNow); if (foundTriangle != null) { return(new MyIntersectionResultLineTriangleEx(foundTriangle.Value, physObject, ref line)); } else { return(null); } }
public override bool GetIntersectionWithLine(ref MyLine line, out Vector3?v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { return(m_gun.GetIntersectionWithLine(ref line, out v, useCollisionModel)); }
/// <summary> /// Returns closest hit from line start position. /// </summary> public bool GetIntersectionWithLine(ref LineD line, ref MyCharacterHitInfo info, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { // TODO: This now uses caspule of physics rigid body on the character, it needs to be changed to ragdoll // Currently this approach will be used to support Characters with different skeleton than humanoid if (info == null) info = new MyCharacterHitInfo(); info.Reset(); bool capsulesReady = UpdateCapsuleBones(); if (!capsulesReady) return false; double closestDistanceToHit = double.MaxValue; Vector3D hitPosition = Vector3D.Zero; Vector3D hitPosition2 = Vector3D.Zero; Vector3 hitNormal = Vector3.Zero; Vector3 hitNormal2 = Vector3.Zero; int capsuleIndex = -1; for (int i = 0; i < m_bodyCapsules.Length; i++) { CapsuleD capsule = m_bodyCapsules[i]; if (capsule.Intersect(line, ref hitPosition, ref hitPosition2, ref hitNormal, ref hitNormal2)) { double distanceToHit = Vector3.Distance(hitPosition, line.From); if (distanceToHit >= closestDistanceToHit) continue; closestDistanceToHit = distanceToHit; capsuleIndex = i; } } if (capsuleIndex != -1) { Matrix worldMatrix = PositionComp.WorldMatrix; int boneIndex = FindBestBone(capsuleIndex, ref hitPosition, ref worldMatrix); // Transform line to model static position and compute accurate collision there // 1. Transform line in local coordinates (used later) Matrix worldMatrixInv = PositionComp.WorldMatrixNormalizedInv; Vector3 fromTrans = Vector3.Transform(line.From, ref worldMatrixInv); Vector3 toTrans = Vector3.Transform(line.To, ref worldMatrixInv); LineD lineLocal = new LineD(fromTrans, toTrans); // 2. Transform line to to bone pose in binding position var bone = AnimationController.CharacterBones[boneIndex]; bone.ComputeAbsoluteTransform(); Matrix boneAbsTrans = bone.AbsoluteTransform; Matrix skinTransform = bone.SkinTransform; Matrix boneTrans = skinTransform * boneAbsTrans; Matrix invBoneTrans = Matrix.Invert(boneTrans); fromTrans = Vector3.Transform(fromTrans, ref invBoneTrans); toTrans = Vector3.Transform(toTrans, ref invBoneTrans); // 3. Move back line to world coordinates LineD lineTransWorld = new LineD(Vector3.Transform(fromTrans, ref worldMatrix), Vector3.Transform(toTrans, ref worldMatrix)); MyIntersectionResultLineTriangleEx? triangle_; bool success = base.GetIntersectionWithLine(ref lineTransWorld, out triangle_, flags); if (success) { MyIntersectionResultLineTriangleEx triangle = triangle_.Value; info.CapsuleIndex = capsuleIndex; info.BoneIndex = boneIndex; info.Capsule = m_bodyCapsules[info.CapsuleIndex]; info.HitHead = info.CapsuleIndex == 0 && m_bodyCapsules.Length > 1; info.HitPositionBindingPose = triangle.IntersectionPointInObjectSpace; info.HitNormalBindingPose = triangle.NormalInObjectSpace; // 4. Move intersection from binding to dynamic pose MyTriangle_Vertexes vertices = new MyTriangle_Vertexes(); vertices.Vertex0 = Vector3.Transform(triangle.Triangle.InputTriangle.Vertex0, ref boneTrans); vertices.Vertex1 = Vector3.Transform(triangle.Triangle.InputTriangle.Vertex1, ref boneTrans); vertices.Vertex2 = Vector3.Transform(triangle.Triangle.InputTriangle.Vertex2, ref boneTrans); Vector3 triangleNormal = Vector3.TransformNormal(triangle.Triangle.InputTriangleNormal, boneTrans); MyIntersectionResultLineTriangle triraw = new MyIntersectionResultLineTriangle(ref vertices, ref triangleNormal, triangle.Triangle.Distance); Vector3 intersectionLocal = Vector3.Transform(triangle.IntersectionPointInObjectSpace, ref boneTrans); Vector3 normalLocal = Vector3.TransformNormal(triangle.NormalInObjectSpace, boneTrans); // 5. Store results triangle = new MyIntersectionResultLineTriangleEx(); triangle.Triangle = triraw; triangle.IntersectionPointInObjectSpace = intersectionLocal; triangle.NormalInObjectSpace = normalLocal; triangle.IntersectionPointInWorldSpace = Vector3.Transform(intersectionLocal, ref worldMatrix); triangle.NormalInWorldSpace = Vector3.TransformNormal(normalLocal, worldMatrix); triangle.InputLineInObjectSpace = lineLocal; info.Triangle = triangle; if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW) { MyRenderProxy.DebugClearPersistentMessages(); MyRenderProxy.DebugDrawCapsule(info.Capsule.P0, info.Capsule.P1, info.Capsule.Radius, Color.Aqua, false, persistent: true); Vector3 p0Local = Vector3.Transform(info.Capsule.P0, ref worldMatrixInv); Vector3 p1Local = Vector3.Transform(info.Capsule.P1, ref worldMatrixInv); Vector3 p0LocalTrans = Vector3.Transform(p0Local, ref invBoneTrans); Vector3 p1LocalTrans = Vector3.Transform(p1Local, ref invBoneTrans); MyRenderProxy.DebugDrawCapsule(Vector3.Transform(p0LocalTrans, ref worldMatrix), Vector3.Transform(p1LocalTrans, ref worldMatrix), info.Capsule.Radius, Color.Brown, false, persistent: true); MyRenderProxy.DebugDrawLine3D(line.From, line.To, Color.Blue, Color.Red, false, true); MyRenderProxy.DebugDrawLine3D(lineTransWorld.From, lineTransWorld.To, Color.Green, Color.Yellow, false, true); MyRenderProxy.DebugDrawSphere(triangle.IntersectionPointInWorldSpace, 0.02f, Color.Red, 1, false, persistent: true); MyRenderProxy.DebugDrawAxis((MatrixD)boneTrans * WorldMatrix, 0.1f, false, true, true); } return true; } } return false; }
internal bool Intersect(ref Line worldLine, out MyIntersectionResultLineTriangleEx?result, IntersectionFlags flags) { Line localLine = new Line(worldLine.From - m_voxelMap.PositionLeftBottomCorner, worldLine.To - m_voxelMap.PositionLeftBottomCorner, true); Profiler.Begin("VoxelMap.LineIntersection AABB sweep"); m_sweepResultCache.Clear(); MyGridIntersection.Calculate( m_sweepResultCache, (int)MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES, localLine.From, localLine.To, new Vector3I(0, 0, 0), m_cellsCount - 1 ); Profiler.End(); Profiler.Begin("VoxelMap.LineIntersection test AABBs"); float? minDistanceUntilNow = null; BoundingBox cellBoundingBox; Vector3I cellCoord; MyIntersectionResultLineTriangle?tmpResult = null; for (int index = 0; index < m_sweepResultCache.Count; index++) { var coord = m_sweepResultCache[index]; cellCoord = coord; GetDataCellBoundingBox(ref cellCoord, out cellBoundingBox); float?distanceToBoundingBox = MyUtils.GetLineBoundingBoxIntersection(ref worldLine, ref cellBoundingBox); // Sweep results are sorted; when we get far enough, make an early exit const float earlyOutDistance = 1.948557f * MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES; // = sqrt(3) * 9/8 * cell_side if (minDistanceUntilNow != null && distanceToBoundingBox != null && minDistanceUntilNow + earlyOutDistance < distanceToBoundingBox.Value) { break; } // Get cell from cache. If not there, precalc it and store in the cache. // If null is returned, we know that cell doesn't contain any triangleVertexes so we don't need to do intersections. CellData cachedDataCell = GetCell(MyLodTypeEnum.LOD0, ref cellCoord); if (cachedDataCell == null || cachedDataCell.VoxelTrianglesCount == 0) { continue; } GetCellLineIntersectionOctree(ref tmpResult, ref localLine, ref minDistanceUntilNow, cachedDataCell, flags); } Profiler.End(); if (tmpResult.HasValue) { result = new MyIntersectionResultLineTriangleEx(tmpResult.Value, m_voxelMap, ref worldLine); return(true); } else { result = null; return(false); } }
// Calculates intersection of line with any triangleVertexes in this model instance. Closest intersection and intersected triangleVertexes will be returned. public virtual bool GetIntersectionWithLine(ref LineD line, out VRage.Game.Models.MyIntersectionResultLineTriangleEx? t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { bool ret = false; t = null; MyModel collisionModel = Model; if (collisionModel != null) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyEntity.GetIntersectionWithLine on model"); VRage.Game.Models.MyIntersectionResultLineTriangleEx? result = collisionModel.GetTrianglePruningStructure().GetIntersectionWithLine(this, ref line, flags); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); if (result != null) { t = result.Value; ret = true; } } return ret; }
public bool GetIntersectionWithLine(ref LineD line, out MyIntersectionResultLineTriangleEx? t, out ushort blockId, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES, bool checkZFight = false, bool ignoreGenerated = false) { t = null; blockId = 0; double distanceSquaredInCompound = double.MaxValue; bool foundIntersection = false; foreach (var blockPair in m_blocks) { MySlimBlock cmpSlimBlock = blockPair.Value; if (ignoreGenerated && cmpSlimBlock.BlockDefinition.IsGeneratedBlock) continue; MyIntersectionResultLineTriangleEx? intersectionTriResult; if (cmpSlimBlock.FatBlock.GetIntersectionWithLine(ref line, out intersectionTriResult) && intersectionTriResult != null) { Vector3D startToIntersection = intersectionTriResult.Value.IntersectionPointInWorldSpace - line.From; double instrDistanceSq = startToIntersection.LengthSquared(); if (instrDistanceSq < distanceSquaredInCompound) { if (checkZFight && distanceSquaredInCompound < instrDistanceSq + 0.001f) continue; distanceSquaredInCompound = instrDistanceSq; t = intersectionTriResult; blockId = blockPair.Key; foundIntersection = true; } } } return foundIntersection; }
/// <summary> /// Gets the intersection with line. /// </summary> /// <param name="line">The line.</param> /// <returns></returns> public override bool GetIntersectionWithLine(ref MyLine line, out MyIntersectionResultLineTriangleEx? t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { t = null; // First check bounding sphere of whole physic object. We must trust that all his childs are inside of default model bounding sphere. Matrix worldMatrix = this.WorldMatrix; BoundingSphere boundingSphere = new BoundingSphere(MyUtils.GetTransform(ModelLod0.BoundingSphere.Center, ref worldMatrix), ModelLod0.BoundingSphere.Radius); if (MyUtils.IsLineIntersectingBoundingSphere(ref line, ref boundingSphere) == false) return false; // Test against default object model MyIntersectionResultLineTriangleEx? intersectionWithBase; base.GetIntersectionWithLine(ref line, out intersectionWithBase); // Test against childs of this phys object (in this case guns) MyIntersectionResultLineTriangleEx? intersectionWithWeapons = Weapons != null ? Weapons.GetIntersectionWithLine(ref line) : null; // Find closer intersection of these two MyIntersectionResultLineTriangleEx? result = MyIntersectionResultLineTriangleEx.GetCloserIntersection(ref intersectionWithBase, ref intersectionWithWeapons); // Only if this is "player's ship" - thus someone is siting in inside (this is an optimization - enemy ships don't render glass decals, they don't need this code) if (this == MySession.PlayerShip) { // Intersection with ideal glass if (GetShipCockpitGlass() != null && GetShipCockpitGlass().ModelLod0 != null && GetShipCockpitGlass().ModelLod0.GetTrianglePruningStructure() != null) { var intersectionGlass = GetShipCockpitGlass().ModelLod0.GetTrianglePruningStructure().GetIntersectionWithLine( GetShipCockpitGlass(), ref line, IntersectionFlags.FLIPPED_TRIANGLES); const float GLASS_DISTANCE_TOLERANCE = 3 * MySmallShipConstants.ALL_SMALL_SHIP_MODEL_SCALE; if (MyIntersectionResultLineTriangleEx.IsDistanceLessThanTolerance(ref result, ref intersectionGlass, GLASS_DISTANCE_TOLERANCE)) { result = intersectionGlass; } } } t = result; return result != null; }
public override bool GetIntersectionWithLine(ref MyLine line, out Vector3? v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { return m_gun.GetIntersectionWithLine(ref line, out v, useCollisionModel); }
private void GetCellLineIntersectionOctree(ref MyIntersectionResultLineTriangle?result, ref Line modelSpaceLine, ref float?minDistanceUntilNow, CellData cachedDataCell, IntersectionFlags flags) { m_overlapElementCache.Clear(); if (cachedDataCell.Octree != null) { Vector3 packedStart; cachedDataCell.GetPackedPosition(ref modelSpaceLine.From, out packedStart); var ray = new Ray(packedStart, modelSpaceLine.Direction); cachedDataCell.Octree.GetIntersectionWithLine(ref ray, m_overlapElementCache); } for (int j = 0; j < m_overlapElementCache.Count; j++) { var i = m_overlapElementCache[j]; if (cachedDataCell.VoxelTriangles == null) //probably not calculated yet { continue; } // this should never happen if (i >= cachedDataCell.VoxelTriangles.Length) { Debug.Assert(i < cachedDataCell.VoxelTriangles.Length); continue; } MyVoxelTriangle voxelTriangle = cachedDataCell.VoxelTriangles[i]; MyTriangle_Vertexes triangleVertices; cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex0, out triangleVertices.Vertex0); cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex1, out triangleVertices.Vertex1); cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex2, out triangleVertices.Vertex2); Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangleVertices); //We dont want backside intersections if (((int)(flags & IntersectionFlags.FLIPPED_TRIANGLES) == 0) && Vector3.Dot(modelSpaceLine.Direction, calculatedTriangleNormal) > 0) { continue; } // AABB intersection test removed, AABB is tested inside BVH float?distance = MyUtils.GetLineTriangleIntersection(ref modelSpaceLine, ref triangleVertices); // If intersection occured and if distance to intersection is closer to origin than any previous intersection if ((distance != null) && ((result == null) || (distance.Value < result.Value.Distance))) { minDistanceUntilNow = distance.Value; result = new MyIntersectionResultLineTriangle(ref triangleVertices, ref calculatedTriangleNormal, distance.Value); } } }
public VRage.Game.Models.MyIntersectionResultLineTriangleEx?GetIntersectionWithLine(IMyEntity entity, ref LineD line, ref MatrixD customInvMatrix, IntersectionFlags flags) { LineD lineInModelSpace = new LineD(Vector3D.Transform(line.From, ref customInvMatrix), Vector3D.Transform(line.To, ref customInvMatrix)); //MyIntersectionResultLineTriangle? result = null; m_result.Start(m_model, lineInModelSpace, flags); var dir = lineInModelSpace.Direction.ToBullet(); var from = lineInModelSpace.From.ToBullet(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("m_bvh.RayQueryClosest()"); m_bvh.RayQueryClosest(ref dir, ref from, m_result.ProcessTriangleHandler); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); if (m_result.Result.HasValue) { return(new VRage.Game.Models.MyIntersectionResultLineTriangleEx(m_result.Result.Value, entity, ref lineInModelSpace)); } else { return(null); } }
/* protected override void Explode() { MyExplosion newExplosion = MyExplosions.AddExplosion(); if (newExplosion != null) { BoundingSphere explosionSphere = WorldVolumeHr; explosionSphere.Radius *= m_config.ExplosionRadiusMultiplier; MyVoxelMap voxelMap = MyVoxelMaps.GetOverlappingWithSphere(ref explosionSphere); MyExplosionDebrisModel.CreateExplosionDebris(ref explosionSphere, MyGroupMask.Empty, this, voxelMap); newExplosion.Start(0, MyPrefabConstants.VOLUME_DAMAGE_MULTIPLIER * m_config.ExplosionDamageMultiplier * WorldVolumeHr.Radius, 0, m_config.ExplosionType, explosionSphere, MyExplosionsConstants.EXPLOSION_LIFESPAN); } } */ public override bool GetIntersectionWithLine(ref MyLine line, out MyIntersectionResultLineTriangleEx? t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { return m_gun.GetIntersectionWithLine(ref line, out t); }
public bool GetIntersectionWithLine(ref LineD line, out MyIntersectionResultLineTriangleEx?t, out ushort blockId, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES, bool checkZFight = false, bool ignoreGenerated = false) { t = null; blockId = 0; double distanceSquaredInCompound = double.MaxValue; bool foundIntersection = false; foreach (var blockPair in m_blocks) { MySlimBlock cmpSlimBlock = blockPair.Value; if (ignoreGenerated && cmpSlimBlock.BlockDefinition.IsGeneratedBlock) { continue; } MyIntersectionResultLineTriangleEx?intersectionTriResult; if (cmpSlimBlock.FatBlock.GetIntersectionWithLine(ref line, out intersectionTriResult) && intersectionTriResult != null) { Vector3D startToIntersection = intersectionTriResult.Value.IntersectionPointInWorldSpace - line.From; double instrDistanceSq = startToIntersection.LengthSquared(); if (instrDistanceSq < distanceSquaredInCompound) { if (checkZFight && distanceSquaredInCompound < instrDistanceSq + 0.001f) { continue; } distanceSquaredInCompound = instrDistanceSq; t = intersectionTriResult; blockId = blockPair.Key; foundIntersection = true; } } } return(foundIntersection); }
public override bool GetIntersectionWithLine(ref MyLine line, out Vector3? v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { BoundingSphere boundingSphere = new BoundingSphere(GetPosition(), BoundingSphereRadius); Ray ray = new Ray(line.From, line.Direction); float? result = ray.Intersects(boundingSphere); v = result.HasValue ? ray.Position + ray.Direction * result.Value : (Vector3?)null; return result.HasValue; }
// Method finds intersection with line and any voxel triangleVertexes in this voxel map. Closes intersection is returned. internal override bool GetIntersectionWithLine(ref LineD worldLine, out MyIntersectionResultLineTriangleEx?t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { t = null; double intersectionDistance; LineD line = (LineD)worldLine; if (!PositionComp.WorldAABB.Intersects(line, out intersectionDistance)) { return(false); } ProfilerShort.Begin("VoxelMap.LineIntersection"); try { Line localLine = new Line(worldLine.From - PositionLeftBottomCorner, worldLine.To - PositionLeftBottomCorner, true); MyIntersectionResultLineTriangle tmpResult; if (Storage.Geometry.Intersect(ref localLine, out tmpResult, flags)) { t = new MyIntersectionResultLineTriangleEx(tmpResult, this, ref worldLine); var tmp = t.Value.IntersectionPointInWorldSpace; tmp.AssertIsValid(); return(true); } else { t = null; return(false); } } finally { ProfilerShort.End(); } }
public VRage.Game.Models.MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(IMyEntity entity, ref LineD line, ref MatrixD customInvMatrix, IntersectionFlags flags) { LineD lineInModelSpace = new LineD(Vector3D.Transform(line.From, ref customInvMatrix), Vector3D.Transform(line.To, ref customInvMatrix)); //MyIntersectionResultLineTriangle? result = null; m_result.Start(m_model, lineInModelSpace, flags); var dir = lineInModelSpace.Direction.ToBullet(); var from = lineInModelSpace.From.ToBullet(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("m_bvh.RayQueryClosest()"); m_bvh.RayQueryClosest(ref dir, ref from, m_result.ProcessTriangleHandler); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); if (m_result.Result.HasValue) { return new VRage.Game.Models.MyIntersectionResultLineTriangleEx(m_result.Result.Value, entity, ref lineInModelSpace); } else { return null; } }
public override bool GetIntersectionWithLine(ref LineD worldLine, out Vector3D?v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { MyIntersectionResultLineTriangleEx?result; GetIntersectionWithLine(ref worldLine, out result); v = null; if (result != null) { v = result.Value.IntersectionPointInWorldSpace; return(true); } return(false); }
public void GetTrianglesIntersectingLine(IMyEntity entity, ref LineD line, ref MatrixD customInvMatrix, IntersectionFlags flags, List<MyIntersectionResultLineTriangleEx> result) { LineD lineInModelSpace = new LineD(Vector3D.Transform(line.From, ref customInvMatrix), Vector3D.Transform(line.To, ref customInvMatrix)); m_resultAll.Start(m_model, lineInModelSpace, flags); var dir = lineInModelSpace.Direction.ToBullet(); var from = lineInModelSpace.From.ToBullet(); VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("m_bvh.RayQueryClosest()"); m_bvh.RayQuery(ref dir, ref from, m_resultAll.ProcessTriangleHandler); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); m_resultAll.End(); foreach (var intersection in m_resultAll.Result) { result.Add(new VRage.Game.Models.MyIntersectionResultLineTriangleEx(intersection, entity, ref lineInModelSpace)); } }
public void GetTrianglesIntersectingLine(IMyEntity entity, ref LineD line, IntersectionFlags flags, List<Sandbox.Common.MyIntersectionResultLineTriangleEx> result) { MatrixD worldInv = entity.GetWorldMatrixNormalizedInv(); GetTrianglesIntersectingLine(entity, ref line, ref worldInv, flags, result); }
// Difference between GetIntersectionWithLine and GetIntersectionWithLineRecursive is that the later doesn't calculate // final result, but is better suited for recursive nature of octree. Don't call GetIntersectionWithLineRecursive() from // the outisde of this class, it's private method. public VRage.Game.Models.MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(IMyEntity physObject, MyModel model, ref LineD line, double? minDistanceUntilNow, IntersectionFlags flags) { VRage.Game.Models.MyIntersectionResultLineTriangle? foundTriangle = GetIntersectionWithLineRecursive(model, ref line, minDistanceUntilNow); if (foundTriangle != null) { return new VRage.Game.Models.MyIntersectionResultLineTriangleEx(foundTriangle.Value, physObject, ref line); } else { return null; } }
private void GetCellLineIntersectionOctree(ref VRage.Game.Models.MyIntersectionResultLineTriangle? result, ref Line modelSpaceLine, ref float? minDistanceUntilNow, CellData cachedDataCell, IntersectionFlags flags) { m_overlapElementCache.Clear(); if (cachedDataCell.Octree != null) { Vector3 packedStart, packedEnd; cachedDataCell.GetPackedPosition(ref modelSpaceLine.From, out packedStart); cachedDataCell.GetPackedPosition(ref modelSpaceLine.To, out packedEnd); var ray = new Ray(packedStart, packedEnd - packedStart); cachedDataCell.Octree.GetIntersectionWithLine(ref ray, m_overlapElementCache); } for (int j = 0; j < m_overlapElementCache.Count; j++) { var i = m_overlapElementCache[j]; if (cachedDataCell.VoxelTriangles == null) //probably not calculated yet continue; // this should never happen if (i >= cachedDataCell.VoxelTriangles.Length) { Debug.Assert(i < cachedDataCell.VoxelTriangles.Length); continue; } MyVoxelTriangle voxelTriangle = cachedDataCell.VoxelTriangles[i]; MyTriangle_Vertexes triangleVertices; cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex0, out triangleVertices.Vertex0); cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex1, out triangleVertices.Vertex1); cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex2, out triangleVertices.Vertex2); Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangleVertices); if (!calculatedTriangleNormal.IsValid()) continue; //We dont want backside intersections if (((int)(flags & IntersectionFlags.FLIPPED_TRIANGLES) == 0) && Vector3.Dot(modelSpaceLine.Direction, calculatedTriangleNormal) > 0) continue; // AABB intersection test removed, AABB is tested inside BVH float? distance = MyUtils.GetLineTriangleIntersection(ref modelSpaceLine, ref triangleVertices); // If intersection occured and if distance to intersection is closer to origin than any previous intersection if ((distance != null) && ((result == null) || (distance.Value < result.Value.Distance))) { minDistanceUntilNow = distance.Value; result = new VRage.Game.Models.MyIntersectionResultLineTriangle(ref triangleVertices, ref calculatedTriangleNormal, distance.Value); } } }
// Calculates intersection of line with object. public virtual bool GetIntersectionWithLine(ref LineD line, out Vector3D?v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { v = null; MyModel collisionModel = Model; if (useCollisionModel) { collisionModel = ModelCollision; } if (collisionModel != null) { MyIntersectionResultLineTriangleEx?result = collisionModel.GetTrianglePruningStructure().GetIntersectionWithLine(this, ref line, flags); if (result != null) { v = result.Value.IntersectionPointInWorldSpace; return(true); } } else { Debug.Assert(false);//this should be overriden by child class if object has no model by default } return(false); }
// Calculates intersection of line with any triangleVertexes in this model instance. Closest intersection and intersected triangleVertexes will be returned. internal override bool GetIntersectionWithLine(ref LineD line, out MyIntersectionResultLineTriangleEx?t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { t = null; return(false); //Matrix invWorld = Matrix.Invert(WorldMatrix); //Vector3 from = Vector3.Transform(line.From, invWorld); //Vector3 to = Vector3.Transform(line.To, invWorld); //Line lineLocal = new Line(from, to); //bool res = base.GetIntersectionWithLine(ref line, out t, flags); //if (res) //{ // var definition = MyDefinitionManager.Static.GetCubeBlockDefinition(new MyDefinitionId(MyObjectBuilderTypeEnum.Ladder)); // if (definition.ExcludedAreaForCamera != null) // { // foreach (var b in definition.ExcludedAreaForCamera) // { // if (b.Contains(t.Value.IntersectionPointInObjectSpace) == ContainmentType.Contains) // { // t = null; // return false; // } // } // } //} //return res; }
public void GetTrianglesIntersectingLine(IMyEntity entity, ref LineD line, ref MatrixD customInvMatrix, IntersectionFlags flags, List<MyIntersectionResultLineTriangleEx> result) { System.Diagnostics.Debug.Assert(false, "Not implemented"); }
// Calculates intersection of line with any triangleVertexes in this model instance. Closest intersection and intersected triangleVertexes will be returned. internal virtual bool GetIntersectionWithLine(ref LineD line, out MyIntersectionResultLineTriangleEx?t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { bool ret = false; t = null; MyModel collisionModel = Model; if (collisionModel != null) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyEntity.GetIntersectionWithLine on model"); MyIntersectionResultLineTriangleEx?result = collisionModel.GetTrianglePruningStructure().GetIntersectionWithLine(this, ref line, flags); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); if (result != null) { t = result.Value; ret = true; } } return(ret); }
public bool Intersect(ref Line localLine, out VRage.Game.Models.MyIntersectionResultLineTriangle result, IntersectionFlags flags) { MyPrecalcComponent.AssertUpdateThread(); ProfilerShort.Begin("VoxelMap.LineIntersection AABB sweep"); m_sweepResultCache.Clear(); MyGridIntersection.Calculate( m_sweepResultCache, (int)MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES, localLine.From, localLine.To, new Vector3I(0, 0, 0), m_cellsCount - 1 ); ProfilerShort.End(); ProfilerShort.Begin("VoxelMap.LineIntersection test AABBs"); float? minDistanceUntilNow = null; BoundingBox cellBoundingBox; MyCellCoord cell = new MyCellCoord(); VRage.Game.Models.MyIntersectionResultLineTriangle? tmpResult = null; for (int index = 0; index < m_sweepResultCache.Count; index++) { cell.CoordInLod = m_sweepResultCache[index]; MyVoxelCoordSystems.GeometryCellCoordToLocalAABB(ref cell.CoordInLod, out cellBoundingBox); float? distanceToBoundingBox = MyUtils.GetLineBoundingBoxIntersection(ref localLine, ref cellBoundingBox); // Sweep results are sorted; when we get far enough, make an early exit const float earlyOutDistance = 1.948557f * MyVoxelConstants.GEOMETRY_CELL_SIZE_IN_METRES; // = sqrt(3) * 9/8 * cell_side if (minDistanceUntilNow != null && distanceToBoundingBox != null && minDistanceUntilNow + earlyOutDistance < distanceToBoundingBox.Value) { break; } // Get cell from cache. If not there, precalc it and store in the cache. // If null is returned, we know that cell doesn't contain any triangleVertexes so we don't need to do intersections. CellData cachedDataCell = GetCell(ref cell); if (cachedDataCell == null || cachedDataCell.VoxelTrianglesCount == 0) continue; GetCellLineIntersectionOctree(ref tmpResult, ref localLine, ref minDistanceUntilNow, cachedDataCell, flags); } ProfilerShort.End(); result = tmpResult ?? default(VRage.Game.Models.MyIntersectionResultLineTriangle); return tmpResult.HasValue; }
// Calculates intersection of line with any triangleVertexes in this model instance. All intersections and intersected triangleVertexes will be returned. internal virtual bool GetIntersectionsWithLine(ref LineD line, List <MyIntersectionResultLineTriangleEx> result, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { MyModel collisionModel = Model; if (collisionModel != null) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyEntity.GetIntersectionWithLine on model"); collisionModel.GetTrianglePruningStructure().GetTrianglesIntersectingLine(this, ref line, flags, result); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } return(result.Count > 0); }
public override bool GetIntersectionWithLine(ref LineD line, out VRage.Game.Models.MyIntersectionResultLineTriangleEx? tri, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { bool ret = GetIntersectionWithLine(ref line, ref m_hitInfoTmp, flags); tri = m_hitInfoTmp.Triangle; return ret; }
public bool GetIntersectionWithLine(ref LineD line, out MyIntersectionResultLineTriangleEx?t, out ushort blockId, IntersectionFlags flags = 3, bool checkZFight = false, bool ignoreGenerated = false) { t = 0; blockId = 0; double maxValue = double.MaxValue; bool flag = false; foreach (KeyValuePair <ushort, MySlimBlock> pair in this.m_mapIdToBlock) { MyIntersectionResultLineTriangleEx?nullable; MySlimBlock block = pair.Value; if ((!ignoreGenerated || !block.BlockDefinition.IsGeneratedBlock) && (block.FatBlock.GetIntersectionWithLine(ref line, out nullable, IntersectionFlags.ALL_TRIANGLES) && (nullable != null))) { double num2 = (nullable.Value.IntersectionPointInWorldSpace - line.From).LengthSquared(); if ((num2 < maxValue) && (!checkZFight || (maxValue >= (num2 + 0.0010000000474974513)))) { maxValue = num2; t = nullable; blockId = pair.Key; flag = true; } } } return(flag); }
// Method finds intersection with line and any voxel triangleVertexes in this voxel map. Closes intersection is returned. internal override bool GetIntersectionWithLine(ref LineD worldLine, out MyIntersectionResultLineTriangleEx? t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { t = null; double intersectionDistance; LineD line = (LineD)worldLine; if (!PositionComp.WorldAABB.Intersects(line, out intersectionDistance)) return false; ProfilerShort.Begin("VoxelMap.LineIntersection"); try { Line localLine = new Line(worldLine.From - PositionLeftBottomCorner, worldLine.To - PositionLeftBottomCorner, true); MyIntersectionResultLineTriangle tmpResult; if (Storage.Geometry.Intersect(ref localLine, out tmpResult, flags)) { t = new MyIntersectionResultLineTriangleEx(tmpResult, this, ref worldLine); var tmp = t.Value.IntersectionPointInWorldSpace; tmp.AssertIsValid(); return true; } else { t = null; return false; } } finally { ProfilerShort.End(); } }
public bool GetIntersectionWithLine_FullyBuiltProgressModels(ref LineD line, out MyIntersectionResultLineTriangleEx?t, out ushort blockId, IntersectionFlags flags = 3, bool checkZFight = false, bool ignoreGenerated = false) { t = 0; blockId = 0; double maxValue = double.MaxValue; bool flag = false; foreach (KeyValuePair <ushort, MySlimBlock> pair in this.m_mapIdToBlock) { MySlimBlock block = pair.Value; if (!ignoreGenerated || !block.BlockDefinition.IsGeneratedBlock) { MyModel modelOnlyData = MyModels.GetModelOnlyData(block.BlockDefinition.Model); if (modelOnlyData != null) { MyIntersectionResultLineTriangleEx?nullable = modelOnlyData.GetTrianglePruningStructure().GetIntersectionWithLine(block.FatBlock, ref line, flags); if (nullable != null) { double num2 = (nullable.Value.IntersectionPointInWorldSpace - line.From).LengthSquared(); if ((num2 < maxValue) && (!checkZFight || (maxValue >= (num2 + 0.0010000000474974513)))) { maxValue = num2; t = nullable; blockId = pair.Key; flag = true; } } } } } return(flag); }
// Calculates intersection of line with object. public virtual bool GetIntersectionWithLine(ref LineD line, out Vector3D? v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { v = null; MyModel collisionModel = Model; if (useCollisionModel) collisionModel = ModelCollision; if (collisionModel != null) { VRage.Game.Models.MyIntersectionResultLineTriangleEx? result = collisionModel.GetTrianglePruningStructure().GetIntersectionWithLine(this, ref line, flags); if (result != null) { v = result.Value.IntersectionPointInWorldSpace; return true; } } else Debug.Assert(false);//this should be overriden by child class if object has no model by default return false; }
/// <summary> /// Calculates intersected block with all models replaced by final models. Useful for construction/deconstruction when models are made from wooden construction. /// </summary> public bool GetIntersectionWithLine_FullyBuiltProgressModels(ref LineD line, out VRage.Game.Models.MyIntersectionResultLineTriangleEx?t, out ushort blockId, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES, bool checkZFight = false, bool ignoreGenerated = false) { t = null; blockId = 0; double distanceSquaredInCompound = double.MaxValue; bool foundIntersection = false; foreach (var blockPair in m_mapIdToBlock) { MySlimBlock cmpSlimBlock = blockPair.Value; if (ignoreGenerated && cmpSlimBlock.BlockDefinition.IsGeneratedBlock) { continue; } MyModel collisionModel = MyModels.GetModelOnlyData(cmpSlimBlock.BlockDefinition.Model); if (collisionModel != null) { VRage.Game.Models.MyIntersectionResultLineTriangleEx?intersectionTriResult = collisionModel.GetTrianglePruningStructure().GetIntersectionWithLine( cmpSlimBlock.FatBlock, ref line, flags); if (intersectionTriResult != null) { Vector3D startToIntersection = intersectionTriResult.Value.IntersectionPointInWorldSpace - line.From; double instrDistanceSq = startToIntersection.LengthSquared(); if (instrDistanceSq < distanceSquaredInCompound) { if (checkZFight && distanceSquaredInCompound < instrDistanceSq + 0.001f) { continue; } distanceSquaredInCompound = instrDistanceSq; t = intersectionTriResult; blockId = blockPair.Key; foundIntersection = true; } } } } return(foundIntersection); }
// Calculates intersection of line with any triangleVertexes in this model instance. All intersections and intersected triangleVertexes will be returned. internal virtual bool GetIntersectionsWithLine(ref LineD line, List<MyIntersectionResultLineTriangleEx> result, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { MyModel collisionModel = Model; if (collisionModel != null) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyEntity.GetIntersectionWithLine on model"); collisionModel.GetTrianglePruningStructure().GetTrianglesIntersectingLine(this, ref line, flags, result); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } return result.Count > 0; }
public override bool GetIntersectionWithLine(ref MyLine line, out Vector3? v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { v = null; Ray ray = new Ray(line.From, line.Direction); float? ds = null; BoundingBox boundingBox = new BoundingBox(WorldMatrix.Translation - Size / 2f, WorldMatrix.Translation + Size / 2f); ds = ray.Intersects(boundingBox); if (ds == null) return false; v = line.From + line.Direction * ds; return true; }