public bool ObjectIntersects(WorldObjectData obj) { foreach (WorldObjectData obj_ in InternalObjects) { if (obj.Intersects(obj_)) { return(true); } } return(false); }
public bool AddObject(WorldObjectData data, bool force = false, bool debug = false) { //Find local chunk position of object Vec2i cPos = World.GetChunkPosition(Vec2i.FromVector3(data.Position)); //The global position of this object Vector3 finalPos = (BaseChunk * World.ChunkSize).AsVector3() + data.Position; //If force, we do not check for collision with other objects. if (force) { if (ObjectMaps[cPos.x, cPos.z] == null) { ObjectMaps[cPos.x, cPos.z] = new List <WorldObjectData>(); } ObjectMaps[cPos.x, cPos.z].Add(data); if (debug) { Debug.Log("Object " + data + " added at local chunk " + cPos + " -> global chunk " + (cPos + BaseChunk) + " total objects now:" + ObjectMaps[cPos.x, cPos.z].Count); } return(true); } if (ObjectMaps[cPos.x, cPos.z] != null) { //iterate all obejcts in chunk, check for intersection foreach (WorldObjectData objDat in ObjectMaps[cPos.x, cPos.z]) { //If we intersect, return false and don't place the object if (data.Intersects(objDat)) { return(false); } } ObjectMaps[cPos.x, cPos.z].Add(data); return(true); } else { ObjectMaps[cPos.x, cPos.z] = new List <WorldObjectData>(); ObjectMaps[cPos.x, cPos.z].Add(data); return(true); } }
/// <summary> /// /// </summary> /// <param name="genRan">The RNG used for this building</param> /// <param name="obj">The object to place in the building</param> /// <param name="height">The height above the ground the object should sit</param> /// <param name="vox">The voxel data of this building. Only required if 'requireWallBacking' is true</param> /// <param name="build">The building to place the object in</param> /// <param name="distFromWall">The distance from a wall the object should be placed</param> /// <param name="wallIndex">Defines the wall we should attempt to place this object on. The 'i'th wall defines the wall /// connecting build.BoundingWall[i] -> build.BoundingWall[i+1]. If left as default value (-1), an index will be randomly generated</param> /// <param name="requireWallBacking">If true, then we will search for a point on the wall that is backed against a wall. /// Used to stop certain objects being placed in front of windows</param> /// <param name="forcePlace">If true, then we do not check for intersection with other objects in the building</param> /// <param name="attemptsCount">The number of attempts made to place the object on this wall</param> /// <returns>True if object is placed sucesfully, false otherwise</returns> public static bool PlaceObjectAgainstWall(GenerationRandom genRan, WorldObjectData obj, float height, BuildingVoxels vox, Building build, float distFromWall = 0, bool requireWallBacking = false, int distToEntr = 2, bool forcePlace = false, int attemptsCount = 5) { if (build.InsideWallPoints == null) { build.InsideWallPoints = FindInsideWallBoundryPoints(vox, build); } //Check attempts count attemptsCount--; if (attemptsCount == 0) { return(false); } float wallDisp = genRan.Random(); //Define the position as the start pos + lambda*dir //Select a random position from all wall points Vec2i pos = genRan.RandomFromArray(build.InsideWallPoints); //If too close to entrance, try another placement if (build.Entrance != null && pos.QuickDistance(build.Entrance) < distToEntr * distToEntr) { return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount)); } //If the object is too close to any of the corners, try again foreach (Vec2i v in build.BoundingWall) { if (v.QuickDistance(pos) < 2) { return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount)); } } Vec2i faceDirection = GetWallPointDirection(build, pos); //If we require a backing wall, we check the position if (requireWallBacking) { Vec2i wPos = pos - faceDirection; for (int y = 0; y < 4; y++) { VoxelNode vn = vox.GetVoxelNode(wPos.x, y, wPos.z); //If there is no node (nothing set) then this position is not valid if (!vn.IsNode) { return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount)); } if (vn.Voxel == Voxel.glass || vn.Voxel == Voxel.none) { return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount)); } } } Vector3 finPos = pos.AsVector3() + faceDirection.AsVector3() * distFromWall + Vector3.up * height; float rotation = Vec2i.Angle(Vec2i.Forward, faceDirection); obj.SetPosition(finPos).SetRotation(rotation); if (!forcePlace) { foreach (WorldObjectData obj_ in build.GetBuildingExternalObjects()) { if (obj.Intersects(obj_)) { return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount)); } } } //obj.SetPosition(finPos); build.AddInternalObject(obj); return(true); }