public void BoundingSphere_CalculatesContainsVector3Correctly() { var sphere = new BoundingSphere(new Vector3(10f, 10f, 10f), 10f); var point1 = new Vector3(11f, 9f, 10f); var result1 = sphere.Contains(point1); var point2 = new Vector3(1000f, 1000f, 1000f); var result2 = sphere.Contains(point2); TheResultingValue(result1) .ShouldBe(ContainmentType.Contains); TheResultingValue(result2) .ShouldBe(ContainmentType.Disjoint); }
internal override ContainmentType Contains(ref BoundingBox queryAabb, ref BoundingSphere querySphere, float lodVoxelSize) { ContainmentType type; ContainmentType type2; BoundingSphere sphere = new BoundingSphere(this.m_translation, this.m_radius + lodVoxelSize); sphere.Contains(ref queryAabb, out type); if (type == ContainmentType.Disjoint) { return(ContainmentType.Disjoint); } sphere.Radius = this.m_radius - lodVoxelSize; sphere.Contains(ref queryAabb, out type2); return((type2 != ContainmentType.Contains) ? ContainmentType.Intersects : ContainmentType.Contains); }
public void ContainsSphere_Disjoint() { var a = new BoundingSphere(Vector3.Zero, 10); var b = new BoundingSphere(new Vector3(15), 8); Assert.AreEqual(ContainmentType.Disjoint, a.Contains(b)); }
public void ContainsSphere_Intersects() { var a = new BoundingSphere(Vector3.Zero, 10); var b = new BoundingSphere(new Vector3(10), 8); Assert.AreEqual(ContainmentType.Intersects, a.Contains(b)); }
public void ContainsSphere_Contains_SmallSphere() { var a = new BoundingSphere(Vector3.Zero, 1); var b = new BoundingSphere(new Vector3(0.5f), 0.1f); Assert.AreEqual(ContainmentType.Contains, a.Contains(b)); }
public void ContainsSphere_Contains() { var a = new BoundingSphere(Vector3.Zero, 10); var b = new BoundingSphere(Vector3.One, 2); Assert.AreEqual(ContainmentType.Contains, a.Contains(b)); }
public void ContainsBoundingBox_Disjoint() { var s = new BoundingSphere(new Vector3(10, 20, 30), 17); var b = new BoundingBox(new Vector3(55, 21, 31), new Vector3(65, 23, 54)); Assert.AreEqual(ContainmentType.Disjoint, s.Contains(b)); }
public ContainmentType IntersectBoundingBox(ref BoundingBox box, float lodLevel) { box.Inflate(1f); bool intersects; BoundingSphere sphere = new BoundingSphere( Vector3.Zero, OuterRadius + lodLevel); sphere.Intersects(ref box, out intersects); if (!intersects) { return(ContainmentType.Disjoint); } sphere.Radius = InnerRadius - lodLevel; ContainmentType ct; sphere.Contains(ref box, out ct); if (ct == ContainmentType.Contains) { return(ContainmentType.Contains); } return(IntersectBoundingBoxInternal(ref box, lodLevel)); }
public void ForEach(BoundingSphere sphere, Predicate <T> predicate, Action <T> action) { if (action == null) { return; } if (Bound.Intersects(sphere)) { if (m_childs.Length == 0) { var items = m_items; for (int index = 0; index < items.Length; index++) { var item = items[index]; if (item == null) { break; } if (sphere.Contains(item.Position) && (predicate?.Invoke(item) ?? true)) { action(item); } } } else { for (int index = 0; index < m_childs.Length; index++) { m_childs[index].ForEach(sphere, predicate, action); } } } Parent?.ForEach(sphere, predicate, action); }
internal bool DoHit(Vector3 pos, Vector3 speed, float damage) { if (Dead || !introTargetReached) { return(true); } if (defending) { Vector2 v2pos = new Vector2(Position.X, Position.Y); BoundingSphere shieldSphere = new BoundingSphere(new Vector3(Helper.PointOnCircle(ref v2pos, 3f, Rotation), Position.Z - 5f), 4f); if (shieldSphere.Contains(pos) == ContainmentType.Contains) { return(false); } } if (timeSinceLastHit <= 0) { for (int i = 0; i < 4; i++) { ParticleController.Instance.Spawn(pos, speed + new Vector3(-0.05f + ((float)Helper.Random.NextDouble() * 0.1f), -0.05f + ((float)Helper.Random.NextDouble() * 0.1f), -0.05f + ((float)Helper.Random.NextDouble() * 0.1f)), 0.5f, new Color(0.5f + ((float)Helper.Random.NextDouble() * 0.5f), 0f, 0f), 1000, true); } timeSinceLastHit = 100; AudioController.PlaySFX("player_hit", 0.5f, -0.2f, 0.2f); } hitAlpha = 1f; Health -= damage; return(true); }
public List <RLight> GetLightsForBounds(BoundingSphere bounds) { List <RLight> affectedLights = new List <RLight>(); foreach (var light in _lights) { if (light.Type == RLightType.DIRECTIONAL) { affectedLights.Add(light); } if (light.Type == RLightType.POINT) { BoundingSphere sphere = new BoundingSphere(light.Position, light.Radius); if (sphere.Intersects(bounds)) { affectedLights.Add(light); } if (sphere.Contains(bounds) != ContainmentType.Disjoint) { affectedLights.Add(light); } } if (affectedLights.Count == 5) { break; } } return(affectedLights); }
public void TestCollisionTree() { var random = new Random(0); Vector3[] points = Enumerable.Range(0, 100) .Select(idx => { float x = (float)random.NextDouble(); float y = (float)random.NextDouble(); float z = (float)random.NextDouble(); return(new Vector3(x, y, z)); }) .ToArray(); var tree = CollisionTree.Make(points); var sphere = new BoundingSphere(new Vector3(0.3f, 0.1f, 0.5f), 0.5f); var indices = tree.GetPointsInSphere(sphere); Assert.IsTrue(indices.Count > 0 && indices.Count < points.Length); var indexSet = new HashSet <int>(indices); for (int idx = 0; idx < points.Length; ++idx) { bool expectedIsInSphere = sphere.Contains(ref points[idx]) == ContainmentType.Contains; bool actualIsInSphere = indexSet.Contains(idx); Assert.AreEqual(expectedIsInSphere, actualIsInSphere); } }
/// <summary> /// Gets the leaf nodes contained into the specified bounding sphere /// </summary> /// <param name="sphere">Bounding sphere</param> /// <returns>Returns the leaf nodes contained into the bounding sphere</returns> public IEnumerable <QuadTreeNode> GetNodesInVolume(ref BoundingSphere sphere) { List <QuadTreeNode> nodes = new List <QuadTreeNode>(); if (this.Children?.Any() == true) { for (int i = 0; i < this.Children.Count; i++) { var childNodes = this.Children[i].GetNodesInVolume(ref sphere); if (childNodes.Any()) { nodes.AddRange(childNodes); } } } else { var bbox = this.BoundingBox; if (sphere.Contains(ref bbox) != ContainmentType.Disjoint) { nodes.Add(this); } } return(nodes.ToArray()); }
public void Explode(Vector3 pos, float radius, bool particles) { BoundingSphere sphere = new BoundingSphere(pos, radius); for (float x = pos.X - radius; x < pos.X + radius; x += Voxel.SIZE) { for (float y = pos.Y - radius; y < pos.Y + radius; y += Voxel.SIZE) { for (float z = pos.Z - radius; z < pos.Z + radius; z += Voxel.SIZE) { Vector3 screen = new Vector3(x, y, z); Vector3 world = FromScreenSpace(screen); if ((int)world.Z >= Z_SIZE - 1) { continue; } if (sphere.Contains(screen) == ContainmentType.Contains) { Voxel v = GetVoxel(screen); if (v.Active && (v.Destructable > 0 || v.Type == VoxelType.Ground)) { SetVoxelActive((int)world.X, (int)world.Y, (int)world.Z, false); if (Helper.Random.Next(20) == 1 && particles) { ParticleController.Instance.Spawn(screen, new Vector3(-0.05f + ((float)Helper.Random.NextDouble() * 0.1f), -0.05f + ((float)Helper.Random.NextDouble() * 0.1f), -((float)Helper.Random.NextDouble() * 1f)), 0.25f, new Color(v.SR, v.SG, v.SB), 1000, true); } } } } } } }
public void ContainsBoundingBox_Intersects() { var s = new BoundingSphere(new Vector3(10, 20, 30), 17); var b = new BoundingBox(new Vector3(11, 21, 31), new Vector3(19, 23, 54)); Assert.AreEqual(ContainmentType.Intersects, s.Contains(b)); }
/// <summary>Iterates over all objects in this Node.</summary> /// <param name="predicate">Returns whether to continue iteration.</param> /// <returns>Whether Iteration was not cancelled (usually indicating that we did not find what we were looking for).</returns> internal bool Iterate(ref BoundingSphere sphere, Func <WorldObject, bool> predicate, uint phase) { if (IsLeaf) { if (HasObjects) { foreach (WorldObject worldObject in m_objects.Values) { Vector3 position = worldObject.Position; if (sphere.Contains(ref position) && worldObject.IsInPhase(phase) && !predicate(worldObject)) { return(false); } } } } else { for (int index1 = 0; index1 < 2; ++index1) { for (int index2 = 0; index2 < 2; ++index2) { ZoneSpacePartitionNode child = m_children[index1, index2]; if (child.Bounds.Intersects(ref sphere).HasAnyFlag(IntersectionType.Touches) && !child.Iterate(ref sphere, predicate, phase)) { return(false); } } } } return(true); }
public IWorldEntity FindEntity(Func <IWorldEntity, bool> criteria, BoundingSphere searchArea) { Contract.Requires(criteria != null); return(RecursiveSearch(criteria, null, 1, x => searchArea.Contains(x.Bounds) == ContainmentType.Contains).SingleOrDefault()); }
public void Select(BoundingSphere sphere, Predicate <T> predicate, List <T> result) { if (result == null) { return; } if (Bound.Intersects(sphere)) { if (m_childs.Length == 0) { var items = m_items; for (int index = 0; index < items.Length; index++) { var item = items[index]; if (item == null) { break; } if (sphere.Contains(item.Position) && (predicate?.Invoke(item) ?? true)) { result.Add(item); } } } else { for (int index = 0; index < m_childs.Length; index++) { m_childs[index].Select(sphere, predicate, result); } } } Parent?.Select(sphere, predicate, result); }
private bool IsTouchingButton(ref float x, ref float y, ref BoundingSphere buttonBounds) { Vector3 point = new Vector3(x, y, 0); buttonBounds.Contains(ref point, out t); return(t == ContainmentType.Contains); }
private bool IsTouchingLeftStick(ref float x, ref float y) { Vector3 point = new Vector3(x, y, 0); leftStickCollision.Contains(ref point, out t); return(t == ContainmentType.Contains); }
private TraverseOptions FindAllBoundingSphere(OctreeNode <List <ISpatialQueryable> > node) { var nodeContainment = ContainmentType.Intersects; boundingSphere.Contains(ref node.bounds, out nodeContainment); if (nodeContainment == ContainmentType.Disjoint) { return(TraverseOptions.Skip); } if (nodeContainment == ContainmentType.Contains) { AddAllDesedents(node); return(TraverseOptions.Skip); } if (node.value != null) { var count = node.value.Count; for (int i = 0; i < count; ++i) { var val = node.value[i]; ContainmentType objectContainment; val.BoundingBox.Contains(ref boundingSphere, out objectContainment); if (objectContainment != ContainmentType.Disjoint) { result.Add(val); } } } return(TraverseOptions.Continue); }
private bool entityIntersectsWithSphere(IMyEntity entity, BoundingSphereD sphere) { IMyCubeGrid grid = entity as IMyCubeGrid; if (grid == null) { log(myLogger, "Asteroid: " + entity.getBestName() + ", " + !ignoreAsteroids, "entityIntersectsWithSphere()", Logger.severity.DEBUG); return(!ignoreAsteroids); //return entity.GetIntersectionWithSphere(ref sphere); // not at all reliable } expensiveTest = true; log(myLogger, "using grid test", "entityIntersectsWithSphere()", Logger.severity.DEBUG); List <IMySlimBlock> blocksInGrid = new List <IMySlimBlock>(); grid.GetBlocks(blocksInGrid); BoundingSphere sphereF = sphere; DateTime beforeBlockCheck = DateTime.UtcNow; foreach (IMySlimBlock block in blocksInGrid) { blocksChecked++; Vector3 worldPos = grid.GridIntegerToWorld(block.Position); if (sphereF.Contains(worldPos) != ContainmentType.Disjoint) { //log(myLogger, "took " + (DateTime.UtcNow - beforeBlockCheck).TotalMilliseconds + " to blockCheck, result=true"); return(true); } } //log(myLogger, "took " + (DateTime.UtcNow - beforeBlockCheck).TotalMilliseconds + " to blockCheck, result=false"); return(false); // nothing found*/ }
public ContainmentType Contains(ref BoundingBox boundingBox) { ContainmentType result; _boundingSphere.Contains(ref boundingBox, out result); return(result); }
public void BoundingSphere_CalculatesContainsBoundingBoxCorrectly() { var sphere = new BoundingSphere(new Vector3(10f, 10f, 10f), 10f); var box1 = new BoundingBox(new Vector3(5f, 5f, 5f), new Vector3(15f, 15f, 15f)); var result1 = sphere.Contains(box1); var box2 = new BoundingBox(new Vector3(-8f, -8f, -8f), new Vector3(8f, 8f, 8f)); var result2 = sphere.Contains(box2); var box3 = new BoundingBox(new Vector3(-1f, -1f, -1f), new Vector3(1f, 1f, 1f)); var result3 = sphere.Contains(box3); TheResultingValue(result1) .ShouldBe(ContainmentType.Contains); TheResultingValue(result2) .ShouldBe(ContainmentType.Intersects); TheResultingValue(result3) .ShouldBe(ContainmentType.Disjoint); }
public void BoundingSphere_CalculatesContainsBoundingSphereCorrectly() { var sphere0 = new BoundingSphere(new Vector3(10f, 10f, 10f), 10f); var sphere1 = new BoundingSphere(new Vector3(10f, 10f, 10f), 5f); var result1 = sphere0.Contains(sphere1); var sphere2 = new BoundingSphere(new Vector3(0, 0, 0), 8f); var result2 = sphere0.Contains(sphere2); var sphere3 = new BoundingSphere(new Vector3(0, 0, 0), 1f); var result3 = sphere0.Contains(sphere3); TheResultingValue(result1) .ShouldBe(ContainmentType.Contains); TheResultingValue(result2) .ShouldBe(ContainmentType.Intersects); TheResultingValue(result3) .ShouldBe(ContainmentType.Disjoint); }
public IEnumerable <IWorldEntity> FindEntities(Func <IWorldEntity, bool> criteria, BoundingSphere searchArea, int maxCount = QuadTree.NoMaxCount) { Contract.Requires(criteria != null); Contract.Requires(maxCount >= QuadTree.NoMaxCount); Contract.Ensures(Contract.Result <IEnumerable <IWorldEntity> >() != null); return(RecursiveSearch(criteria, null, maxCount, x => searchArea.Contains(x.Bounds) == ContainmentType.Contains)); }
public bool Filter(RigidBody body) { var center = new SlimDX.Vector3(body.MotionState.WorldTransform.M41, body.MotionState.WorldTransform.M42, body.MotionState.WorldTransform.M43); var ct = BoundingSphere.Contains(Bounds, center); return(this.Containments.Contains(ct)); }
public void CreateMerged_Contains2() { var a = new BoundingSphere(new Vector3(1, 0, 0), 2); var b = new BoundingSphere(Vector3.Zero, 5); var m = BoundingSphere.CreateMerged(a, b); Assert.AreEqual(ContainmentType.Contains, b.Contains(a)); Assert.AreEqual(ContainmentType.Intersects, a.Contains(b)); Assert.AreEqual(b, m); }
internal override ContainmentType Contains(ref BoundingBox queryAabb, ref BoundingSphere querySphere, float lodVoxelSize) { ContainmentType outerContainment, innerContainment; BoundingSphere sphere = new BoundingSphere( m_translation, m_radius + lodVoxelSize); sphere.Contains(ref queryAabb, out outerContainment); if (outerContainment == ContainmentType.Disjoint) return ContainmentType.Disjoint; sphere.Radius = m_radius - lodVoxelSize; sphere.Contains(ref queryAabb, out innerContainment); if (innerContainment == ContainmentType.Contains) return ContainmentType.Contains; return ContainmentType.Intersects; }
public static bool isCollided(BoundingSphere a, BoundingSphere b) { ContainmentType ct = a.Contains(b); ContainmentType ct2 = b.Contains(a); if (ct != ContainmentType.Disjoint || ct2 != ContainmentType.Disjoint) { return(true); } return(false); }
//check for collision with the race marker public bool checkCollision(BoundingSphere carShere) { if (collisionSphere.Contains(carShere) != ContainmentType.Disjoint) { return(true); } else { return(false); } }
/// <summary> /// List the GameObjects outside this octree leaf. /// </summary> /// <param name="gameObjects">A list of GameObjects.</param> /// <returns>A list of objects from the list that are outside this leaf.</returns> public List<GameObject> outsideOctree(List<GameObject> gameObjects) { List<GameObject> outsideObjects = new List<GameObject>(); foreach (GameObject obj in gameObjects) { BoundingSphere objSphere = new BoundingSphere(obj.position.pos(), obj.size); if(containerBox.Contains(objSphere) == ContainmentType.Disjoint && objSphere.Contains(containerBox) == ContainmentType.Disjoint) { //outsideObjects.Add(obj); } } return outsideObjects; }
public bool Collision(BoundingSphere primarySphere, BoundingSphere secondarySphere) { //example of what a circle code should look like //primarySphere = new BoundingSphere(new Vector3(center, 0), center.Length()); ContainmentType contains = primarySphere.Contains(secondarySphere); if (primarySphere.Intersects(secondarySphere) || contains == ContainmentType.Intersects) { return true; } else { return false; } }
internal void ReadContentRange(ref MyVoxelDataRequest req) { if (Closed) return; float lodVoxelSize = (1 << req.Lod) * MyVoxelConstants.VOXEL_SIZE_IN_METRES; Vector3I min = req.minInLod; Vector3I max = req.maxInLod; ProfilerShort.Begin("Distance field computation"); try { Vector3I v = min; Vector3 localPos = v * lodVoxelSize - m_translation; Vector3 localPosStart = localPos; BoundingBox request = new BoundingBox(localPos, localPos + (max - min) * lodVoxelSize); request.Inflate(lodVoxelSize); MyVoxelRequestFlags flags = 0; ContainmentType cont = ContainmentType.Intersects; bool intersects; if (!req.Flags.HasFlag(MyVoxelRequestFlags.DoNotCheck)) { BoundingSphere sphere = new BoundingSphere( Vector3.Zero, OuterRadius + lodVoxelSize); sphere.Intersects(ref request, out intersects); if (!intersects) { cont = ContainmentType.Disjoint; goto end; } sphere.Radius = InnerRadius - lodVoxelSize; ContainmentType ct; sphere.Contains(ref request, out ct); if (ct == ContainmentType.Contains) { cont = ct; goto end; } cont = IntersectBoundingBoxInternal(ref request, lodVoxelSize); if (cont != ContainmentType.Intersects) goto end; } bool hit = false; // store request history EnqueueHistory(req); // Setup cache for current map; PrepareCache(); var writeOffsetLoc = req.Offset - min; for (v.Z = min.Z; v.Z <= max.Z; ++v.Z) { for (v.Y = min.Y; v.Y <= max.Y; ++v.Y) { v.X = min.X; var write2 = v + writeOffsetLoc; var write = req.Target.ComputeLinear(ref write2); for (; v.X <= max.X; ++v.X) { float signedDist = SignedDistanceLocal(localPos, lodVoxelSize) / lodVoxelSize; var fillRatio = MathHelper.Clamp(-signedDist, -1f, 1f) * 0.5f + 0.5f; byte content = (byte)(fillRatio * MyVoxelConstants.VOXEL_CONTENT_FULL); if (content != 0) { hit = true; } req.Target.Content(write, content); write += req.Target.StepLinear; localPos.X += lodVoxelSize; } localPos.Y += lodVoxelSize; localPos.X = localPosStart.X; } localPos.Z += lodVoxelSize; localPos.Y = localPosStart.Y; } if (!hit) { PruningStats.Miss(); } else { PruningStats.Hit(); } CullStats.Miss(); return; end: ; CullStats.Hit(); if (cont == ContainmentType.Disjoint) { if (req.RequestFlags.HasFlag(MyVoxelRequestFlags.ContentChecked)) { flags |= MyVoxelRequestFlags.EmptyContent | MyVoxelRequestFlags.ContentCheckedDeep | MyVoxelRequestFlags.ContentChecked; } else { req.Target.BlockFillContent(req.Offset, req.Offset + max - min, MyVoxelConstants.VOXEL_CONTENT_EMPTY); } } else if (cont == ContainmentType.Contains) { if (req.RequestFlags.HasFlag(MyVoxelRequestFlags.ContentChecked)) { flags |= MyVoxelRequestFlags.FullContent | MyVoxelRequestFlags.ContentCheckedDeep | MyVoxelRequestFlags.ContentChecked; } else { req.Target.BlockFillContent(req.Offset, req.Offset + max - min, MyVoxelConstants.VOXEL_CONTENT_FULL); } } req.Flags = flags; PruningStats.Hit(); } finally { ProfilerShort.End(); } }
public ContainmentType IntersectBoundingBox(ref BoundingBox box, float lodLevel) { box.Inflate(1f); bool intersects; BoundingSphere sphere = new BoundingSphere( Vector3.Zero, OuterRadius + lodLevel); sphere.Intersects(ref box, out intersects); if (!intersects) { return ContainmentType.Disjoint; } sphere.Radius = InnerRadius - lodLevel; ContainmentType ct; sphere.Contains(ref box, out ct); if (ct == ContainmentType.Contains) { return ContainmentType.Contains; } return IntersectBoundingBoxInternal(ref box, lodLevel); }
public void Explode(Vector3 pos, float radius, bool particles) { BoundingSphere sphere = new BoundingSphere(pos, radius); for(float x=pos.X-radius;x<pos.X+radius;x+= Voxel.SIZE) for(float y=pos.Y-radius;y<pos.Y+radius;y+= Voxel.SIZE) for (float z = pos.Z - radius; z < pos.Z + radius; z+= Voxel.SIZE) { Vector3 screen = new Vector3(x, y, z); Vector3 world = FromScreenSpace(screen); if ((int)world.Z >= Z_SIZE - 1) continue; if (sphere.Contains(screen) == ContainmentType.Contains) { Voxel v = GetVoxel(screen); if (v.Active && (v.Destructable > 0 || v.Type== VoxelType.Ground)) { SetVoxelActive((int)world.X, (int)world.Y, (int)world.Z, false); if(Helper.Random.Next(20)==1 && particles) ParticleController.Instance.Spawn(screen, new Vector3(-0.05f + ((float)Helper.Random.NextDouble() * 0.1f), -0.05f + ((float)Helper.Random.NextDouble() * 0.1f), -((float)Helper.Random.NextDouble() * 1f)), 0.25f, new Color(v.SR, v.SG, v.SB), 1000, true); } } } }
internal override ContainmentType Contains(ref BoundingBox queryAabb, ref BoundingSphere querySphere, float lodVoxelSize) { ContainmentType outerContainment, innerContainment; BoundingSphere sphere = new BoundingSphere( m_translation, m_outerRadius+ lodVoxelSize); sphere.Contains(ref queryAabb, out outerContainment); if (outerContainment == ContainmentType.Disjoint) return ContainmentType.Disjoint; sphere.Radius = m_innerRadius - lodVoxelSize; sphere.Contains(ref queryAabb, out innerContainment); if (innerContainment == ContainmentType.Contains) return ContainmentType.Contains; float minDistance = float.MaxValue; float maxDistance = -float.MaxValue; Vector3 localPosition = queryAabb.Min - m_translation; float distance = localPosition.LengthSquared(); if(distance < 0.01f) { return ContainmentType.Intersects; } Vector3I samplePos; Vector2 pos = Vector2.Zero; MyCsgPrecomputedHelpres.CalculateSamplePosition(ref localPosition, out samplePos, ref pos, m_header.Resolution); float value = GetValueForPosition(ref samplePos, ref pos, true); minDistance = MathHelper.Min(minDistance, value); maxDistance = MathHelper.Max(maxDistance, value); localPosition = queryAabb.Max - m_translation; distance = localPosition.LengthSquared(); if (distance < 0.01f) { return ContainmentType.Intersects; } MyCsgPrecomputedHelpres.CalculateSamplePosition(ref localPosition, out samplePos, ref pos, m_header.Resolution); value = GetValueForPosition(ref samplePos, ref pos, true); minDistance = MathHelper.Min(minDistance, value); maxDistance = MathHelper.Max(maxDistance, value); sphere.Radius = m_innerRadius + maxDistance + lodVoxelSize; sphere.Contains(ref queryAabb, out outerContainment); if (outerContainment == ContainmentType.Disjoint) return ContainmentType.Disjoint; sphere.Radius = m_innerRadius + minDistance - lodVoxelSize; sphere.Contains(ref queryAabb, out innerContainment); if (innerContainment == ContainmentType.Contains) return ContainmentType.Contains; return ContainmentType.Intersects; }
internal bool DoHit(Vector3 pos, Vector3 speed, float damage) { if (Dead || !introTargetReached) return true; if (defending) { Vector2 v2pos = new Vector2(Position.X, Position.Y); BoundingSphere shieldSphere = new BoundingSphere(new Vector3(Helper.PointOnCircle(ref v2pos, 3f, Rotation), Position.Z-5f), 4f); if(shieldSphere.Contains(pos)== ContainmentType.Contains) return false; } if (timeSinceLastHit <= 0) { for (int i = 0; i < 4; i++) { ParticleController.Instance.Spawn(pos, speed + new Vector3(-0.05f + ((float)Helper.Random.NextDouble() * 0.1f), -0.05f + ((float)Helper.Random.NextDouble() * 0.1f), -0.05f + ((float)Helper.Random.NextDouble() * 0.1f)), 0.5f, new Color(0.5f + ((float)Helper.Random.NextDouble() * 0.5f), 0f, 0f), 1000, true); } timeSinceLastHit = 100; AudioController.PlaySFX("player_hit", 0.5f, -0.2f, 0.2f); } hitAlpha = 1f; Health -= damage; return true; }
private bool IsTouchingButton(ref float x, ref float y, ref BoundingSphere buttonBounds) { Vector3 point = new Vector3(x, y, 0); buttonBounds.Contains(ref point, out t); return (t == ContainmentType.Contains); }
public static ContainmentType Contains(ref BoundingSphere s1, ref BoundingBox b1) { return s1.Contains(b1); }
internal override ContainmentType Contains(ref BoundingBox queryAabb, ref BoundingSphere querySphere, float lodVoxelSize) { ContainmentType outerContainment, innerContainment; BoundingSphere sphere = new BoundingSphere( m_translation, m_outerRadius + lodVoxelSize); sphere.Contains(ref queryAabb, out outerContainment); if (outerContainment == ContainmentType.Disjoint) return ContainmentType.Disjoint; sphere.Radius = m_innerRadius - lodVoxelSize; sphere.Contains(ref queryAabb, out innerContainment); if (innerContainment == ContainmentType.Contains) return ContainmentType.Contains; if (m_cachedNoise != null) { float minDistance = m_canyonHalfDeviation; float maxDistance = -m_hillHalfDeviation; unsafe { const int cornersLength = 8; Vector3* corners = stackalloc Vector3[cornersLength]; queryAabb.GetCornersUnsafe(corners); bool first = true; for (int i = 0; i < cornersLength; ++i) { Vector3 localPosition = corners[i] - m_translation; float distanceMin = localPosition.Length(); localPosition.Normalize(); Vector2 encodedPosition = Vector2.Zero; Encode(ref localPosition, ref encodedPosition); Vector2 samplePosition = encodedPosition * NOISE_RESOLUTION; Vector2I position = Vector2I.Floor(samplePosition); Vector2 unpackedValue = m_cachedNoise[position.X*(NOISE_RESOLUTION + 1)+position.Y].ToVector2(); if (first) { minDistance = unpackedValue.Y; maxDistance = unpackedValue.X; first = false; } else { minDistance = MathHelper.Max(minDistance, unpackedValue.Y); maxDistance = MathHelper.Min(maxDistance, unpackedValue.X); } } } sphere.Radius = m_shapeAttributes.Radius - maxDistance + lodVoxelSize; sphere.Contains(ref queryAabb, out outerContainment); if (outerContainment == ContainmentType.Disjoint) return ContainmentType.Disjoint; sphere.Radius = m_shapeAttributes.Radius - minDistance - lodVoxelSize; sphere.Contains(ref queryAabb, out innerContainment); if (innerContainment == ContainmentType.Contains) return ContainmentType.Contains; } return ContainmentType.Intersects; }
protected override void LoadContent() { _model = Content.Load<Model>(_fileName); var skinningData = _model.Tag as SkinningData; if (skinningData != null) { _animationPlayer = new AnimationPlayer(skinningData); var clip = skinningData.AnimationClips["Take 001"]; _animationPlayer.StartClip(clip); _bones = _animationPlayer.GetSkinTransforms(); } else { _bones = new Matrix[_model.Bones.Count]; _model.CopyAbsoluteBoneTransformsTo(_bones); } var bestFit = new BoundingSphere(); foreach (var mesh in _model.Meshes) { if (bestFit.Contains(mesh.BoundingSphere) != ContainmentType.Contains) bestFit = BoundingSphere.CreateMerged(bestFit, mesh.BoundingSphere); } _worldMatrix = Matrix.Identity; _viewMatrix = Matrix.CreateTranslation(bestFit.Center) * Matrix.CreateTranslation(0, -bestFit.Radius * 1.5f, -bestFit.Radius * 4); _projMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 0.1f, bestFit.Radius * 2 * 10.0f); foreach (var mesh in _model.Meshes) { foreach (var effect in mesh.Effects) { var em = effect as IEffectMatrices; em.World = _worldMatrix; em.View = _viewMatrix; em.Projection = _projMatrix; var basic = effect as BasicEffect; if (basic != null) basic.EnableDefaultLighting(); var skinned = effect as SkinnedEffect; if (skinned != null) skinned.EnableDefaultLighting(); } } }
public bool GetIntersection(ref BoundingSphere sphere, ref Vector3 velocityNormal, int polyIndex, out OCTreeIntersection intersection) { var flag = false; intersection = new OCTreeIntersection(); var plane = Planes[polyIndex]; if (plane.DotNormal(velocityNormal) < 0f) { if (plane.DotCoordinate(sphere.Center) < 0f) { return false; } if (plane.Intersects(sphere) != PlaneIntersectionType.Intersecting) { return false; } var a = Vertices[Indices[polyIndex * 3]]; var b = Vertices[Indices[(polyIndex * 3) + 1]]; var c = Vertices[Indices[(polyIndex * 3) + 2]]; var p = Intersection.ClosestPointOnPlane(sphere.Center, plane); if (Intersection.PointInTriangle(p, a, b, c)) { intersection.IntersectionPoint = p; intersection.IntersectionNormal = plane.Normal; intersection.IntersectionDepth = sphere.Radius - Vector3.Distance(p, sphere.Center); intersection.Node = this; intersection.PolygonIndex = polyIndex; intersection.IntersectType = OCTreeIntersectionType.Inside; flag = true; } else { float num; Vector3 vector5; if (sphere.Contains(a) != ContainmentType.Disjoint) { intersection.IntersectionPoint = a; intersection.IntersectionNormal = Vector3.Normalize(sphere.Center - a); intersection.IntersectionDepth = sphere.Radius - Vector3.Distance(a, sphere.Center); intersection.Node = this; intersection.PolygonIndex = polyIndex; intersection.IntersectType = OCTreeIntersectionType.Point; return true; } if (sphere.Contains(b) != ContainmentType.Disjoint) { intersection.IntersectionPoint = b; intersection.IntersectionNormal = Vector3.Normalize(sphere.Center - b); intersection.IntersectionDepth = sphere.Radius - Vector3.Distance(b, sphere.Center); intersection.Node = this; intersection.PolygonIndex = polyIndex; intersection.IntersectType = OCTreeIntersectionType.Point; return true; } if (sphere.Contains(c) != ContainmentType.Disjoint) { intersection.IntersectionPoint = c; intersection.IntersectionNormal = Vector3.Normalize(sphere.Center - c); intersection.IntersectionDepth = sphere.Radius - Vector3.Distance(c, sphere.Center); intersection.Node = this; intersection.PolygonIndex = polyIndex; intersection.IntersectType = OCTreeIntersectionType.Point; return true; } Intersection.ClosestPointOnSegment(sphere.Center, a, b, out num, out vector5); if (sphere.Contains(vector5) != ContainmentType.Disjoint) { intersection.IntersectionPoint = vector5; intersection.IntersectionNormal = Vector3.Normalize(sphere.Center - vector5); intersection.IntersectionDepth = sphere.Radius - Vector3.Distance(vector5, sphere.Center); intersection.IntersectType = OCTreeIntersectionType.Edge; intersection.Node = this; intersection.PolygonIndex = polyIndex; return true; } Intersection.ClosestPointOnSegment(sphere.Center, b, c, out num, out vector5); if (sphere.Contains(vector5) != ContainmentType.Disjoint) { intersection.IntersectionPoint = vector5; intersection.IntersectionNormal = Vector3.Normalize(sphere.Center - vector5); intersection.IntersectionDepth = sphere.Radius - Vector3.Distance(vector5, sphere.Center); intersection.IntersectType = OCTreeIntersectionType.Edge; intersection.Node = this; intersection.PolygonIndex = polyIndex; flag = true; } else { Intersection.ClosestPointOnSegment(sphere.Center, c, a, out num, out vector5); if (sphere.Contains(vector5) != ContainmentType.Disjoint) { intersection.IntersectionPoint = vector5; intersection.IntersectionNormal = Vector3.Normalize(sphere.Center - vector5); intersection.IntersectionDepth = sphere.Radius - Vector3.Distance(vector5, sphere.Center); intersection.IntersectType = OCTreeIntersectionType.Edge; intersection.Node = this; intersection.PolygonIndex = polyIndex; flag = true; } } } } return flag; }
public void MoveSphere(ref BoundingSphere sphere, ref Vector3 sphereVelocity, float Friction, ref List<OCTreeIntersection> sphereColliders) { int num4; var vector = sphereVelocity; var velocityNormal = Vector3.Normalize(vector); var sphere2 = new BoundingSphere(sphere.Center + vector, sphere.Radius); var list = new List<OCTreeIntersection>(); sphere2.Radius = sphere.Radius + vector.Length(); GetIntersectingPolygons(ref sphere2, ref velocityNormal, ref list); sphere2.Radius = sphere.Radius; for (var i = 0; i < 5; i++) { var num2 = 0; for (var j = 0; j < list.Count; j++) { var intersection = list[j]; if (intersection.Node.UpdateIntersection(ref intersection, ref sphere2, ref velocityNormal) && (sphere2.Contains(intersection.IntersectionPoint) != ContainmentType.Disjoint)) { num2++; var vector3 = (intersection.IntersectionNormal * (intersection.IntersectionDepth + 0.001f)); sphere2.Center += vector3; vector = sphere2.Center - sphere.Center; velocityNormal = Vector3.Normalize(vector); var flag = false; num4 = 0; while (num4 < sphereColliders.Count) { if ((sphereColliders[num4].Node == intersection.Node) && (sphereColliders[num4].PolygonIndex == intersection.PolygonIndex)) { flag = true; break; } num4++; } if (!flag) { sphereColliders.Add(intersection); } } } if (num2 == 0) { break; } } var flag2 = false; for (num4 = 0; num4 < sphereColliders.Count; num4++) { if (Vector3.Dot(sphereColliders[num4].IntersectionNormal, Vector3.Up) > 0.5f) { vector -= ((vector * (Vector3.One - Vector3.Up)) * Friction); flag2 = true; break; } } if (!flag2) { vector -= (((vector * (Vector3.One - Vector3.Up)) * Friction) * 0.5f); } sphereVelocity = vector; sphere = sphere2; }
public bool Overlap(BoundingSphere sphere) { for (int t = 0; t < tiles.Length; t++) { if (!tiles[t].BoundingBox.Intersects(sphere)) continue; for (int i = 0; i < indices.Length / 3; i++) { int index0 = indices[i * 3]; int index1 = indices[i * 3 + 1]; int index2 = indices[i * 3 + 2]; Vector3[] triangle = new Vector3[] { tiles[t].Vertices[index0].Position, tiles[t].Vertices[index1].Position, tiles[t].Vertices[index2].Position, }; for(int j = 0; j < 3; j++ ) if( sphere.Contains(triangle[j]) != ContainmentType.Disjoint ) return true; } } return false; }
// collision improve karanna ona private CollisionType CheckCollision(BoundingSphere shipSphere, BoundingSphere warningSphere) { if (shipPosition.X > terrainPosition.X) { positionOnHeightMap = new Vector3((shipPosition.X - terrainPosition.X), 0, shipPosition.Z); int left = (int)positionOnHeightMap.X; int top = (int)-positionOnHeightMap.Z; float xNormalized = (positionOnHeightMap.X % 1) / 1; // here terrainscale=1 float zNormalized = (-positionOnHeightMap.Z % 1) / 1; float topHeight = MathHelper.Lerp(heightData[left, top], heightData[left + 1, top], xNormalized); float bottomHeight = MathHelper.Lerp(heightData[left, top + 1], heightData[left + 1, top + 1], xNormalized); float positionheight = MathHelper.Lerp(topHeight, bottomHeight, zNormalized); p1 = new Vector3(shipPosition.X, positionheight, shipPosition.Z); terrainSphere= new BoundingSphere(p1,0.01f); if (terrainSphere.Contains(shipSphere) != ContainmentType.Disjoint) { return CollisionType.Terrain; } else if (terrainSphere.Contains(warningSphere) != ContainmentType.Disjoint) { return CollisionType.Warning; } } for (int i = 0; i < buildingBoundingBoxes.Length; i++) { if (buildingBoundingBoxes[i].Contains(shipSphere) != ContainmentType.Disjoint) return CollisionType.Building; if (buildingBoundingBoxes[i].Contains(warningSphere) != ContainmentType.Disjoint) return CollisionType.Warning; } for (int i = 0; i < itemList.Count; i++) { if (itemList[i].Contains(shipSphere) != ContainmentType.Disjoint) { itemList.RemoveAt(i); i--; //AddTargets(); return CollisionType.Item; } } if (completeWorldBox.Contains(shipSphere) != ContainmentType.Contains) { return CollisionType.Boundary; } else if (completeWorldBox.Contains(warningSphere) != ContainmentType.Contains) { return CollisionType.Warning; } return CollisionType.None; }
public override void Process(Camera camera, GameTime gameTime) { #if DEBUG stopwatch.Restart(); #endif Game.GraphicsDevice.SetRenderTarget(Outputs["Light"]); Game.GraphicsDevice.Clear(new Color(AmbientLight.R, AmbientLight.G, AmbientLight.B, 0)); Vector3[] frustumCorners = camera.Frustum.GetCorners(); for (int i = 0; i < 4; i++) frustumCorners[i] = frustumCorners[i + 4]; Vector3 corner = frustumCorners[2]; frustumCorners[2] = frustumCorners[3]; frustumCorners[3] = corner; pointLightEffect.Parameters["CameraPosition"].SetValue(camera.Position); pointLightEffect.Parameters["FarPlane"].SetValue(camera.FarPlane); pointLightEffect.Parameters["FrustumCorners"].SetValue(camera.Frustum.GetCorners()); pointLightEffect.Parameters["Normal"].SetValue(Inputs["Normal"]); pointLightEffect.Parameters["Depth"].SetValue(Inputs["Depth"]); pointLightEffect.Parameters["Color"].SetValue(Inputs["Color"]); spotLightEffect.Parameters["CameraPosition"].SetValue(camera.Position); spotLightEffect.Parameters["FarPlane"].SetValue(camera.FarPlane); spotLightEffect.Parameters["FrustumCorners"].SetValue(camera.Frustum.GetCorners()); spotLightEffect.Parameters["Normal"].SetValue(Inputs["Normal"]); spotLightEffect.Parameters["Depth"].SetValue(Inputs["Depth"]); spotLightEffect.Parameters["Color"].SetValue(Inputs["Color"]); directionalLightEffect.Parameters["CameraPosition"].SetValue(camera.Position); directionalLightEffect.Parameters["FarPlane"].SetValue(camera.FarPlane); directionalLightEffect.Parameters["FrustumCorners"].SetValue(camera.Frustum.GetCorners()); directionalLightEffect.Parameters["Normal"].SetValue(Inputs["Normal"]); directionalLightEffect.Parameters["Depth"].SetValue(Inputs["Depth"]); directionalLightEffect.Parameters["Color"].SetValue(Inputs["Color"]); #region PointLights Game.GraphicsDevice.BlendState = BlendState.Additive; foreach (PointLight light in Lights.OfType<PointLight>()) { // FIXME BoundingSphere boundingSphere = new BoundingSphere(light.Position, light.Radius); if (boundingSphere.Contains(camera.Position) != ContainmentType.Disjoint) Game.GraphicsDevice.RasterizerState = RasterizerState.CullNone; else Game.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; pointLightEffect.Parameters["LightPosition"].SetValue(light.Position); pointLightEffect.Parameters["LightColor"].SetValue(light.Color.ToVector4()); pointLightEffect.Parameters["LightIntensity"].SetValue(light.Intensity); pointLightEffect.Parameters["LightRadius"].SetValue(light.Radius); sphere.Position = light.Position; sphere.Scale = new Vector3(light.Radius * 1.2f); sphere.Effect = pointLightEffect; sphere.Draw(camera, gameTime); } #endregion #region SpotLights Game.GraphicsDevice.BlendState = BlendState.Additive; foreach (SpotLight light in Lights.OfType<SpotLight>()) { BoundingSphere boundingSphere = new BoundingSphere(light.Position, light.Radius); if (boundingSphere.Contains(camera.Position) == ContainmentType.Contains) Game.GraphicsDevice.RasterizerState = RasterizerState.CullClockwise; else Game.GraphicsDevice.RasterizerState = RasterizerState.CullCounterClockwise; spotLightEffect.Parameters["LightPosition"].SetValue(light.Position); spotLightEffect.Parameters["LightColor"].SetValue(light.Color.ToVector4()); spotLightEffect.Parameters["LightIntensity"].SetValue(light.Intensity); spotLightEffect.Parameters["LightRadius"].SetValue(light.Radius); spotLightEffect.Parameters["LightDirection"].SetValue(light.Direction); spotLightEffect.Parameters["LightAngle"].SetValue(light.Angle); // FIXME cone.Position = light.Position; cone.Rotation = Vector3Utils.GetQuaternion(Vector3.Up, light.Direction); float vScale = light.Radius; float hScale = (float)Math.Cos(light.Angle) * light.Radius * 1.2f; cone.Scale = new Vector3(hScale, vScale, hScale); cone.Effect = spotLightEffect; cone.Draw(camera, gameTime); } #endregion #region DirectionalLights Game.GraphicsDevice.BlendState = BlendState.Additive; foreach (DirectionalLight light in Lights.OfType<DirectionalLight>()) { directionalLightEffect.Parameters["LightColor"].SetValue(light.Color.ToVector4()); directionalLightEffect.Parameters["LightIntensity"].SetValue(light.Intensity); directionalLightEffect.Parameters["LightDirection"].SetValue(light.Direction); directionalLightEffect.CurrentTechnique.Passes[0].Apply(); Game.GraphicsDevice.ComputeShader(); } #endregion #if DEBUG processTimes.Enqueue((int)stopwatch.ElapsedTicks); while (processTimes.Count > 60) processTimes.Dequeue(); #endif }
public static ContainmentType Contains(ref BoundingSphere s1, ref BoundingSphere s2) { return s1.Contains(s2); }
/// <summary> /// Split this octree leaf into child leaves. /// </summary> protected void split() { Vector3 half = (containerBox.Max - containerBox.Min) / 2; Vector3 halfx = Vector3.UnitX * half; Vector3 halfy = Vector3.UnitY * half; Vector3 halfz = Vector3.UnitZ * half; BoundingBox[] boxes = { new BoundingBox(containerBox.Min, containerBox.Min + half), new BoundingBox(containerBox.Min + halfx, containerBox.Min + half + halfx), new BoundingBox(containerBox.Min + halfy, containerBox.Min + half + halfy), new BoundingBox(containerBox.Min + halfz, containerBox.Min + half + halfz), new BoundingBox(containerBox.Min + halfx + halfy, containerBox.Min + half + halfx + halfy), new BoundingBox(containerBox.Min + halfx + halfz, containerBox.Min + half + halfx + halfz), new BoundingBox(containerBox.Min + halfy + halfz, containerBox.Min + half + halfy + halfz), new BoundingBox(containerBox.Min + half, containerBox.Max) }; childLeaves.Clear(); foreach( BoundingBox tempBox in boxes) { OctreeLeaf tempLeaf = new OctreeLeaf(tempBox, maxDepth, currentDepth+1); foreach(GameObject obj in containedObjects){ BoundingSphere objSphere = new BoundingSphere(obj.position.pos(), obj.size); if (tempBox.Contains(objSphere) != ContainmentType.Disjoint || objSphere.Contains(tempBox) != ContainmentType.Disjoint) { tempLeaf.containedObjects.Add(obj); } } if (currentDepth < maxDepth && tempLeaf.containedObjects.Count != 0){ tempLeaf.split(); } childLeaves.Add(tempLeaf); } if (debugOctreeDepth) { Console.WriteLine("Current node depth: " + currentDepth + " Next depth: " + (currentDepth + 1)); } }
// Based on existing code available on the Internet // See: http://realtimerendering.com/intersections.html // Converted to C# for XNA /// <summary> /// This is an expensive test. /// </summary> public void Intersects(ref BoundingSphere sphere, out bool result) { result = false; // First check if any corner point is inside the sphere // This is necessary because the other tests can easily miss // small triangles that are fully inside the sphere. if (sphere.Contains(A) != ContainmentType.Disjoint || sphere.Contains(B) != ContainmentType.Disjoint || sphere.Contains(C) != ContainmentType.Disjoint) { // A point is inside the sphere result = true; return; } // Test the edges of the triangle using a ray // If any hit then check the distance to the hit is less than the length of the side // The distance from a point of a small triangle inside the sphere coule be longer // than the edge of the small triangle, hence the test for points inside above. Vector3 side = B - A; // Important: The direction of the ray MUST // be normalised otherwise the resulting length // of any intersect is wrong! Ray ray = new Ray(A, Vector3.Normalize(side)); float distSq = 0; float? length = null; sphere.Intersects(ref ray, out length); if (length != null) { distSq = (float)length * (float)length; if (length > 0 && distSq < side.LengthSquared()) { // Hit edge result = true; return; } } // Stay at A and change the direction to C side = C - A; ray.Direction = Vector3.Normalize(side); length = null; sphere.Intersects(ref ray, out length); if (length != null) { distSq = (float)length * (float)length; if (length > 0 && distSq < side.LengthSquared()) { // Hit edge result = true; return; } } // Change to corner B and edge to C side = C - B; ray.Position = B; ray.Direction = Vector3.Normalize(side); length = null; sphere.Intersects(ref ray, out length); if (length != null) { distSq = (float)length * (float)length; if (length > 0 && distSq < side.LengthSquared()) { // Hit edge result = true; return; } } // If we get this far we are not touching the edges of the triangle // Calculate the InverseNormal of the triangle from the centre of the sphere // Do a ray intersection from the centre of the sphere to the triangle. // If the triangle is too small the ray could miss a small triangle inside // the sphere hence why the points were tested above. ray.Position = sphere.Center; // This will always create a vector facing towards the triangle from the // ray starting point. InverseNormal(ref ray.Position, out side); ray.Direction = side; Intersects(ref ray, out length); if (length != null && length > 0 && length < sphere.Radius) { // Hit the surface of the triangle result = true; return; } // Only if we get this far have we missed the triangle result = false; }
public bool Intersects(ref BoundingSphere sphere, ref Vector3[] triangle, out bool onEdge) { Ray ray = new Ray(); onEdge = true; float? length; Vector3 A = triangle[0], B = triangle[1], C = triangle[2]; Vector3 side = B - A; ray = new Ray(A, Vector3.Normalize(side)); float distSq = 0; length = null; sphere.Intersects(ref ray, out length); if (length != null) { distSq = (float)length * (float)length; if (length > 0 && distSq < side.LengthSquared()) { return true; } } side = C - A; ray.Direction = Vector3.Normalize(side); length = null; sphere.Intersects(ref ray, out length); if (length != null) { distSq = (float)length * (float)length; if (length > 0 && distSq < side.LengthSquared()) { return true; } } side = C - B; ray.Position = B; ray.Direction = Vector3.Normalize(side); length = null; sphere.Intersects(ref ray, out length); if (length != null) { distSq = (float)length * (float)length; if (length > 0 && distSq < side.LengthSquared()) { return true; } } if (sphere.Contains(A) != ContainmentType.Disjoint || sphere.Contains(B) != ContainmentType.Disjoint || sphere.Contains(C) != ContainmentType.Disjoint) { return true; } onEdge = false; ray.Position = sphere.Center; ray.Direction = -getNormalToTriangle(ref triangle); Intersects(ref ray, ref triangle, out length); if (length != null && length > 0 && length < sphere.Radius) { return true; } return false; }
/// <summary> /// Returns a list of the extremities of the triangle that /// are fully within the sphere. /// This is sufficient for collission testing but is not /// intended to be an accurate cross section. /// Triangles larger than the sphere return points that touch /// the edges of the bounding sphere where the triangle sides /// penetrates the sphere or if all three points are outside /// tey return the nearest point on the sphere which is sufficient /// to get an approximate section of the sphere. /// Returns an empty list if the triangle does not intersect the sphere. /// This is an expensive test. Use at design time only. /// </summary> public List<Vector3> PointsInsideSphere(BoundingSphere sphere) { List<Vector3> result = new List<Vector3>(); // Test which if any points are inside the sphere for (int p = 0; p < Vertex.Length; p++) { if (sphere.Contains(Vertex[p]) != ContainmentType.Disjoint) { // == Inside the sphere result.Add(Vertex[p]); } else { // == Outside the sphere // Test both side eminating from the point to see where they // intersect the sphere, if at all. int other = GetAnyOtherIndex(p); Vector3 side = Vertex[other] - Vertex[p]; // Important: The direction of the ray MUST // be normalised otherwise the resulting length // of any intersect is wrong! Ray ray = new Ray(Vertex[p], Vector3.Normalize(side)); float distSq = 0; float? length = null; sphere.Intersects(ref ray, out length); if (length != null) { distSq = (float)length * (float)length; if (length > 0 && distSq < side.LengthSquared()) { // The side of the triangle hits the edge of the sphere // so save the point of impact. result.Add(ray.Position + (ray.Direction * (float)length)); } } else { // Side is fully outside the sphere Vector3? impact = IntersectNearestOnPlane(sphere, p); if (impact != null) { result.Add((Vector3)impact); } } // Get the other corner other = GetOtherIndex(other, p); // Same point but the other edge side = Vertex[other] - Vertex[p]; ray.Direction = Vector3.Normalize(side); length = null; sphere.Intersects(ref ray, out length); if (length != null) { distSq = (float)length * (float)length; if (length > 0 && distSq < side.LengthSquared()) { // The side of the triangle hits the edge of the sphere // so save the point of impact. result.Add(ray.Position + (ray.Direction * (float)length)); } } else { // Side is fully outside the sphere Vector3? impact = IntersectNearestOnPlane(sphere, p); if (impact != null) { result.Add((Vector3)impact); } } } } return result; }
private void CheckCollision() { for (int i = 0; i < numBullets; i++) { if (bulletList[i].active) { //create shere for bullet BoundingSphere sphere = new BoundingSphere(bulletList[i].Translation, 1f); for (int j = 0; j < numTargets; j++) { if (targetList[j].active) { //create shere for the targets BoundingSphere sphere2 = new BoundingSphere(targetList[j].Translation, 4.0f); if (sphere2.Contains(sphere) != ContainmentType.Disjoint) { // make target and bullet colliding disappear targetList[j].active = false; bulletList[i].active = false; //score for hitting target score += 10; } } } } } }