public void Evaluate(int SpreadMax) { if (this.FWorld.PluginIO.IsConnected) { this.FHit.SliceCount = SpreadMax; this.FHitCount.SliceCount = SpreadMax; List <double> fraction = new List <double>(); List <Vector3D> position = new List <Vector3D>(); List <Vector3D> normal = new List <Vector3D>(); List <RigidBody> body = new List <RigidBody>(); List <int> bodyid = new List <int>(); List <int> qidx = new List <int>(); for (int i = 0; i < SpreadMax; i++) { Vector3 from = this.FFrom[i].ToBulletVector(); Vector3 to = this.FTo[i].ToBulletVector(); if (cb == null) { cb = new CollisionWorld.AllHitsRayResultCallback(from, to); } cb.HitFractions.Clear(); cb.HitNormalWorld.Clear(); cb.HitPointWorld.Clear(); cb.CollisionObjects.Clear(); this.FWorld[0].World.RayTest(from, to, cb); if (cb.HasHit) { this.FHitCount[i] = cb.HitFractions.Count; float minfrac = float.MaxValue; RigidBody closest = null; int minidx = 0; for (int h = 0; h < cb.HitFractions.Count; h++) { RigidBody rb = (RigidBody)cb.CollisionObjects[h]; if (cb.HitFractions[h] < minfrac && !this.FExcludedBody.Contains(rb)) { closest = rb; minidx = h; } } if (closest != null) { this.FHit[i] = true; BodyCustomData bd = (BodyCustomData)closest.UserObject; fraction.Add(cb.HitFractions[minidx]); position.Add(cb.HitPointWorld[minidx].ToVVVVector()); normal.Add(cb.HitNormalWorld[minidx].ToVVVVector()); body.Add(closest); bodyid.Add(bd.Id); qidx.Add(i); } else { this.FHit[i] = false; } } else { this.FHit[i] = false; this.FHitCount[i] = 0; } } this.FId.AssignFrom(bodyid); this.FHitFraction.AssignFrom(fraction); this.FHitNormal.AssignFrom(normal); this.FHitPosition.AssignFrom(position); this.FQueryIndex.AssignFrom(qidx); this.FBody.AssignFrom(body); } else { this.FHit.SliceCount = 0; this.FId.SliceCount = 0; this.FHitFraction.SliceCount = 0; this.FHitPosition.SliceCount = 0; this.FHitCount.SliceCount = 0; } }
/// <summary> /// レイキャスト /// </summary> /// <param name="start">開始地点(ワールド座標)</param> /// <param name="end">終了地点(ワールド座標)</param> /// <param name="collideWith">コリジョン対象のビット列</param> /// <returns></returns> public IEnumerable<RaycastResult> RayCast(Vector3 start, Vector3 end, int collideWith = -1) { var from = new BulletSharp.Vector3 (start.X, start.Y, start.Z); var to = new BulletSharp.Vector3 (end.X, end.Y, end.Z); using (var result = new CollisionWorld.AllHitsRayResultCallback (from, to)) { result.CollisionFilterMask = (CollisionFilterGroups)collideWith; // BulletPhysics のレイキャスト wld.RayTest (from, to, result); if (!result.HasHit) { return new RaycastResult[0]; } var n = result.HitFractions.Count (); var results = new RaycastResult[n]; for (var i = 0; i < n; i++) { var frac = result.HitFractions[i]; var dist = frac * (start - end).Length; var node = ((CollisionObject)result.CollisionObjects[i].UserObject).Node; var point = result.HitPointWorld[i].ToDD (); var normal = result.HitNormalWorld[i].ToDD(); results[i] = new RaycastResult (frac, dist, node, point, normal); } return results.OrderBy (x => x.Fraction); } }
public void Evaluate(int SpreadMax) { if (this.FWorld.PluginIO.IsConnected) { this.FHit.SliceCount = SpreadMax; this.FHitCount.SliceCount = SpreadMax; List<double> fraction = new List<double>(); List<Vector3D> position = new List<Vector3D>(); List<Vector3D> normal = new List<Vector3D>(); List<RigidBody> body = new List<RigidBody>(); List<int> bodyid = new List<int>(); List<int> qidx = new List<int>(); for (int i = 0; i < SpreadMax; i++) { Vector3 from = this.FFrom[i].ToBulletVector(); Vector3 to = this.FTo[i].ToBulletVector(); if (cb == null) { cb = new CollisionWorld.AllHitsRayResultCallback(from, to); } cb.HitFractions.Clear(); cb.HitNormalWorld.Clear(); cb.HitPointWorld.Clear(); cb.CollisionObjects.Clear(); this.FWorld[0].World.RayTest(from, to, cb); if (cb.HasHit) { this.FHitCount[i] = cb.HitFractions.Count; float minfrac = float.MaxValue; RigidBody closest = null; int minidx = 0; for (int h = 0; h < cb.HitFractions.Count; h++ ) { RigidBody rb = (RigidBody)cb.CollisionObjects[h]; if (cb.HitFractions[h] < minfrac && !this.FExcludedBody.Contains(rb)) { closest = rb; minidx = h; } } if (closest != null) { this.FHit[i] = true; BodyCustomData bd = (BodyCustomData)closest.UserObject; fraction.Add(cb.HitFractions[minidx]); position.Add(cb.HitPointWorld[minidx].ToVVVVector()); normal.Add(cb.HitNormalWorld[minidx].ToVVVVector()); body.Add(closest); bodyid.Add(bd.Id); qidx.Add(i); } else { this.FHit[i] = false; } } else { this.FHit[i] = false; this.FHitCount[i] = 0; } } this.FId.AssignFrom(bodyid); this.FHitFraction.AssignFrom(fraction); this.FHitNormal.AssignFrom(normal); this.FHitPosition.AssignFrom(position); this.FQueryIndex.AssignFrom(qidx); this.FBody.AssignFrom(body); } else { this.FHit.SliceCount = 0; this.FId.SliceCount = 0; this.FHitFraction.SliceCount = 0; this.FHitPosition.SliceCount = 0; this.FHitCount.SliceCount = 0; } }