public FVec3 RestrictInBounds(ITileObject tileObject, bool ignoreObstacle) { int index = this.GlobalPointToLocalIndex(tileObject.position); FBounds bounds = this.GetTileBounds(index); FVec3 min = bounds.min; FVec3 max = bounds.max; FVec3 halfSize = tileObject.worldBounds.size * Fix64.Half; FVec3 p = tileObject.position; if ((ignoreObstacle || this._tiles[index + 1].flag != Tile.Flag.Walkable) && p.x > max.x - halfSize.x) { p.x = max.x - halfSize.x; } else if ((ignoreObstacle || this._tiles[index - 1].flag != Tile.Flag.Walkable) && p.x < min.x + halfSize.x) { p.x = min.x + halfSize.x; } if ((ignoreObstacle || this._tiles[index - this.col].flag != Tile.Flag.Walkable) && p.z > max.z - halfSize.z) { p.z = max.z - halfSize.z; } else if ((ignoreObstacle || this._tiles[index + this.col].flag != Tile.Flag.Walkable) && p.z < min.z + halfSize.z) { p.z = min.z + halfSize.z; } return(p); }
private FBounds GetTileBounds(int index) { FVec3 p = this.LocalIndexToGlobalPoint(index); p.z -= this.scale.z; FBounds bounds = new FBounds(); bounds.min = p; bounds.max = bounds.min + this.scale; return(bounds); }
public Fix64 MoveDetection(ITileObject self, Fix64 distance, int direction) { if (distance == Fix64.Zero) { return(Fix64.Zero); } FBounds bounds = self.worldBounds; FVec3 position = bounds.center; position.y = Fix64.Zero; int girdIndex = this.GlobalPointToLocalIndex(position); Fix64 minT; if (direction == 0) //x轴 { if (distance > Fix64.Zero) //右 { this.GetRightNeighborBounds(self, girdIndex, ref this._tmpBounds); } else if (distance < Fix64.Zero) //左 { this.GetLeftNeighborBounds(self, girdIndex, ref this._tmpBounds); } minT = this.GetMinIntersectTime(bounds, this._tmpBounds, distance, FBounds.Axis.X); this._tmpBounds.Clear(); } else //z轴 { if (distance > Fix64.Zero) { this.GetUpNeighborBounds(self, girdIndex, ref this._tmpBounds); } else if (distance < Fix64.Zero) { this.GetDownNeighborBounds(self, girdIndex, ref this._tmpBounds); } minT = this.GetMinIntersectTime(bounds, this._tmpBounds, distance, FBounds.Axis.Z); this._tmpBounds.Clear(); } distance = minT * distance; return(distance); }
public bool Intersects(FBounds boundingBox) { FVec3 clampedLocation; if (this.center.x > boundingBox.max.x) { clampedLocation.x = boundingBox.max.x; } else if (this.center.x < boundingBox.min.x) { clampedLocation.x = boundingBox.min.x; } else { clampedLocation.x = this.center.x; } if (this.center.y > boundingBox.max.y) { clampedLocation.y = boundingBox.max.y; } else if (this.center.y < boundingBox.min.y) { clampedLocation.y = boundingBox.min.y; } else { clampedLocation.y = this.center.y; } if (this.center.z > boundingBox.max.z) { clampedLocation.z = boundingBox.max.z; } else if (this.center.z < boundingBox.min.z) { clampedLocation.z = boundingBox.min.z; } else { clampedLocation.z = this.center.z; } return(clampedLocation.DistanceSquared(this.center) <= this.radius * this.radius); }
private Fix64 GetMinIntersectTime(FBounds movingBounds, List <FBounds> staticBounds, Fix64 d, FBounds.Axis axis) { Fix64 minT = Fix64.MaxValue; foreach (FBounds b in staticBounds) { if (!b.IntersectMovingBoundsByAxis(movingBounds, d, axis, out Fix64 t)) { continue; } if (t >= minT) { continue; } minT = t; } return(minT > Fix64.One ? Fix64.One : minT); }
public EntityData(string id) { this.id = id; Hashtable def = Defs.GetEntity(this.id); this.name = def.GetString("name"); this.model = def.GetString("model"); this.naturalSpeed = def.GetFix64("natural_speed"); FVec3 size = def.GetFVec3("size"); this.bounds = new FBounds(new FVec3(Fix64.Zero, size.y * Fix64.Half, Fix64.Zero), size); this.fov = def.GetFix64("fov"); this.triggerRadius = def.GetFix64("trigger_raduis"); Hashtable triggerDef = def.GetMap("trigger"); if (triggerDef != null) { this.trigger = new TriggerData(triggerDef); } }
public bool Intersects(FBounds boundingBox, out Fix64 result) { // X if (Fix64.Abs(this.direction.x) < Fix64.Epsilon && (this.origin.x < boundingBox.min.x || this.origin.x > boundingBox.max.x)) { //If the ray isn't pointing along the axis at all, and is outside of the box's interval, then it can't be intersecting. result = Fix64.Zero; return(false); } Fix64 tmin = Fix64.Zero, tmax = Fix64.MaxValue; Fix64 inverseDirection = Fix64.One / this.direction.x; Fix64 t1 = (boundingBox.min.x - this.origin.x) * inverseDirection; Fix64 t2 = (boundingBox.max.x - this.origin.x) * inverseDirection; if (t1 > t2) { Fix64 temp = t1; t1 = t2; t2 = temp; } tmin = Fix64.Max(tmin, t1); tmax = Fix64.Min(tmax, t2); if (tmin > tmax) { result = Fix64.Zero; return(false); } // Y if (Fix64.Abs(this.direction.y) < Fix64.Epsilon && (this.origin.y < boundingBox.min.y || this.origin.y > boundingBox.max.y)) { //If the ray isn't pointing along the axis at all, and is outside of the box's interval, then it can't be intersecting. result = Fix64.Zero; return(false); } inverseDirection = Fix64.One / this.direction.y; t1 = (boundingBox.min.y - this.origin.y) * inverseDirection; t2 = (boundingBox.max.y - this.origin.y) * inverseDirection; if (t1 > t2) { Fix64 temp = t1; t1 = t2; t2 = temp; } tmin = Fix64.Max(tmin, t1); tmax = Fix64.Min(tmax, t2); if (tmin > tmax) { result = Fix64.Zero; return(false); } // Z if (Fix64.Abs(this.direction.z) < Fix64.Epsilon && (this.origin.z < boundingBox.min.z || this.origin.z > boundingBox.max.z)) { //If the ray isn't pointing along the axis at all, and is outside of the box's interval, then it can't be intersecting. result = Fix64.Zero; return(false); } inverseDirection = Fix64.One / this.direction.z; t1 = (boundingBox.min.z - this.origin.z) * inverseDirection; t2 = (boundingBox.max.z - this.origin.z) * inverseDirection; if (t1 > t2) { Fix64 temp = t1; t1 = t2; t2 = temp; } tmin = Fix64.Max(tmin, t1); tmax = Fix64.Min(tmax, t2); if (tmin > tmax) { result = Fix64.Zero; return(false); } result = tmin; return(true); }