예제 #1
0
 // TODO: Optimize tracing!
 public Structure(Region tregion, Location startOfTrace, int maxrad)
 {
     startOfTrace = startOfTrace.GetBlockLocation();
     Queue<Location> locs = new Queue<Location>();
     HashSet<Location> found = new HashSet<Location>();
     List<Location> resultLocs = new List<Location>();
     locs.Enqueue(startOfTrace);
     int maxradsq = maxrad * maxrad;
     AABB box = new AABB() { Max = startOfTrace, Min = startOfTrace };
     while (locs.Count > 0)
     {
         Location loc = locs.Dequeue();
         if (found.Contains(loc))
         {
             continue;
         }
         if (loc.DistanceSquared(startOfTrace) > maxradsq)
         {
             throw new Exception("Escaped radius!");
         }
         BlockInternal bi = tregion.GetBlockInternal(loc);
         if ((Material)bi.BlockMaterial == Material.AIR)
         {
             continue;
         }
         if (!((BlockFlags)bi.BlockLocalData).HasFlag(BlockFlags.EDITED))
         {
             throw new Exception("Found natural block!");
         }
         if (((BlockFlags)bi.BlockLocalData).HasFlag(BlockFlags.PROTECTED))
         {
             throw new Exception("Found protected block!");
         }
         found.Add(loc);
         resultLocs.Add(loc);
         box.Include(loc);
         foreach (Location dir in FloodDirs)
         {
             locs.Enqueue(loc + dir);
         }
     }
     Location ext = box.Max - box.Min;
     Size = new Vector3i((int)ext.X + 1, (int)ext.Y + 1, (int)ext.Z + 1);
     Origin = new Vector3i((int)Math.Floor(startOfTrace.X - box.Min.X), (int)Math.Floor(startOfTrace.Y - box.Min.Y), (int)Math.Floor(startOfTrace.Z - box.Min.Z));
     Blocks = new BlockInternal[Size.X * Size.Y * Size.Z];
     foreach (Location loc in resultLocs)
     {
         Blocks[BlockIndex((int)(loc.X - box.Min.X), (int)(loc.Y - box.Min.Y), (int)(loc.Z - box.Min.Z))] = tregion.GetBlockInternal(loc);
     }
 }
예제 #2
0
 public override bool ParseBytesAndExecute(byte[] data)
 {
     if (data.Length < 4)
     {
         return false;
     }
     int len = Utilities.BytesToInt(Utilities.BytesPartial(data, 0, 4));
     if (data.Length != 4 + 24 * 2 * len)
     {
         return false;
     }
     AABB[] boxes = new AABB[len];
     for (int i = 0; i < len; i++)
     {
         boxes[i] = new AABB();
         boxes[i].Min = Location.FromDoubleBytes(data, 4 + i * 24 * 2);
         boxes[i].Max = Location.FromDoubleBytes(data, 4 + i * 24 * 2 + 24);
     }
     TheClient.TheRegion.Highlights = boxes;
     return true;
 }
예제 #3
0
 // TODO: EFficiency needed so much!
 public override void Execute(PlayerCommandEntry entry)
 {
     if (entry.InputArguments.Count < 1)
     {
         entry.Player.SendMessage(TextChannel.COMMAND_RESPONSE, "/blockship <convex/perfect> [scale]");
         return;
     }
     BGETraceMode tm = BGETraceMode.CONVEX;
     if (entry.InputArguments[0].ToLowerFast() == "perfect")
     {
         tm = BGETraceMode.PERFECT;
     }
     double maxRad = 20; // TODO: Config!
     Location start = (entry.Player.GetPosition() + new Location(0, 0, -0.1)).GetBlockLocation();
     List<KeyValuePair<Location, BlockInternal>> blocks = new List<KeyValuePair<Location, BlockInternal>>();
     AABB extent = new AABB() { Min = start, Max = start };
     if (!FloodFrom(entry.Player.TheRegion, start, blocks, maxRad, extent) || blocks.Count == 0)
     {
         entry.Player.SendMessage(TextChannel.COMMAND_RESPONSE, "Invalid flood-search!");
         return;
     }
     Location size = extent.Max - extent.Min;
     int xwidth = (int)size.X + 1;
     int ywidth = (int)size.Y + 1;
     int zwidth = (int)size.Z + 1;
     int xsub = (int)extent.Min.X;
     int ysub = (int)extent.Min.Y;
     int zsub = (int)extent.Min.Z;
     BlockInternal[] blocksin = new BlockInternal[xwidth * ywidth * zwidth];
     foreach (KeyValuePair<Location, BlockInternal> block in blocks)
     {
         entry.Player.TheRegion.SetBlockMaterial(block.Key, Material.AIR, 0, 0, 1, 0, true, true, true);
         blocksin[(int)(block.Key.Z - zsub) * ywidth * xwidth + (int)(block.Key.Y - ysub) * xwidth + (int)(block.Key.X - xsub)] = block.Value;
     }
     BlockGroupEntity bge = new BlockGroupEntity(extent.Min, tm, entry.Player.TheRegion, blocksin, xwidth, ywidth, zwidth);
     bge.scale = entry.InputArguments.Count < 2 ? Location.One : Location.FromString(entry.InputArguments[1]);
     entry.Player.TheRegion.SpawnEntity(bge);
 }
예제 #4
0
 bool FloodFrom(Region tregion, Location start, List<KeyValuePair<Location, BlockInternal>> blocks, double maxRad, AABB extent)
 {
     Queue<Location> locsToGo = new Queue<Location>();
     locsToGo.Enqueue(start);
     while (locsToGo.Count > 0)
     {
         Location c = locsToGo.Dequeue();
         if ((c - start).LengthSquared() > maxRad * maxRad)
         {
             SysConsole.Output(OutputType.INFO, "Escaped radius!");
             return false;
         }
         BlockInternal bi = tregion.GetBlockInternal(c);
         if ((Material)bi.BlockMaterial == Material.AIR)
         {
             continue;
         }
         if (!((BlockFlags)bi.BlockLocalData).HasFlag(BlockFlags.EDITED))
         {
             SysConsole.Output(OutputType.INFO, "Found natural block!");
             return false;
         }
         if (((BlockFlags)bi.BlockLocalData).HasFlag(BlockFlags.PROTECTED))
         {
             continue;
         }
         blocks.Add(new KeyValuePair<Location, BlockInternal>(c, bi));
         tregion.SetBlockMaterial(c, (Material)bi.BlockMaterial, bi.BlockData, bi.BlockPaint, (byte)(bi.BlockLocalData | (byte)BlockFlags.PROTECTED), bi.Damage, false, false);
         extent.Include(c);
         foreach (Location dir in FloodDirs)
         {
             locsToGo.Enqueue(c + dir);
         }
     }
     return true;
 }
예제 #5
0
파일: Region.cs 프로젝트: Morphan1/Voxalia
 public bool SpecialCaseRayTrace(Location start, Location dir, float len, MaterialSolidity considerSolid, Func<BroadPhaseEntry, bool> filter, out RayCastResult rayHit)
 {
     Ray ray = new Ray(start.ToBVector(), dir.ToBVector());
     RayCastResult best = new RayCastResult(new RayHit() { T = len }, null);
     bool hA = false;
     if (considerSolid.HasFlag(MaterialSolidity.FULLSOLID))
     {
         RayCastResult rcr;
         if (PhysicsWorld.RayCast(ray, len, filter, out rcr))
         {
             best = rcr;
             hA = true;
         }
     }
     AABB box = new AABB();
     box.Min = start;
     box.Max = start;
     box.Include(start + dir * len);
     foreach (KeyValuePair<Vector3i, Chunk> chunk in LoadedChunks)
     {
         if (chunk.Value == null || chunk.Value.FCO == null)
         {
             continue;
         }
         if (!box.Intersects(new AABB() { Min = chunk.Value.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE, Max = chunk.Value.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE + new Location(Chunk.CHUNK_SIZE) }))
         {
             continue;
         }
         RayHit temp;
         if (chunk.Value.FCO.RayCast(ray, len, null, considerSolid, out temp))
         {
             hA = true;
             //temp.T *= len;
             if (temp.T < best.HitData.T)
             {
                 best.HitData = temp;
                 best.HitObject = chunk.Value.FCO;
             }
         }
     }
     rayHit = best;
     return hA;
 }
예제 #6
0
파일: Region.cs 프로젝트: Morphan1/Voxalia
 public bool SpecialCaseConvexTrace(ConvexShape shape, Location start, Location dir, float len, MaterialSolidity considerSolid, Func<BroadPhaseEntry, bool> filter, out RayCastResult rayHit)
 {
     RigidTransform rt = new RigidTransform(start.ToBVector(), BEPUutilities.Quaternion.Identity);
     BEPUutilities.Vector3 sweep = (dir * len).ToBVector();
     RayCastResult best = new RayCastResult(new RayHit() { T = len }, null);
     bool hA = false;
     if (considerSolid.HasFlag(MaterialSolidity.FULLSOLID))
     {
         RayCastResult rcr;
         if (PhysicsWorld.ConvexCast(shape, ref rt, ref sweep, filter, out rcr))
         {
             best = rcr;
             hA = true;
         }
     }
     sweep = dir.ToBVector();
     AABB box = new AABB();
     box.Min = start;
     box.Max = start;
     box.Include(start + dir * len);
     foreach (KeyValuePair<Vector3i, Chunk> chunk in LoadedChunks)
     {
         if (chunk.Value == null || chunk.Value.FCO == null)
         {
             continue;
         }
         if (!box.Intersects(new AABB() { Min = chunk.Value.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE, Max = chunk.Value.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE + new Location(Chunk.CHUNK_SIZE) }))
         {
             continue;
         }
         RayHit temp;
         if (chunk.Value.FCO.ConvexCast(shape, ref rt, ref sweep, len, considerSolid, out temp))
         {
             hA = true;
             //temp.T *= len;
             if (temp.T < best.HitData.T)
             {
                 best.HitData = temp;
                 best.HitObject = chunk.Value.FCO;
             }
         }
     }
     rayHit = best;
     return hA;
 }
예제 #7
0
 public void renderGame()
 {
     Stopwatch totalt = new Stopwatch();
     totalt.Start();
     try
     {
         MainWorldView.ForwardVec = Player.ForwardVector();
         // Frustum cf1 = null;
         if (CVars.g_firstperson.ValueB)
         {
             MainWorldView.CameraPos = PlayerEyePosition;
         }
         else
         {
             CollisionResult cr = TheRegion.Collision.RayTrace(PlayerEyePosition, PlayerEyePosition - MainWorldView.CalcForward() * Player.ViewBackMod(), IgnorePlayer);
             if (cr.Hit)
             {
                 MainWorldView.CameraPos = cr.Position + cr.Normal * 0.05;
             }
             else
             {
                 MainWorldView.CameraPos = cr.Position;
             }
         }
         if (CVars.u_showmap.ValueB && mapLastRendered + 1.0 < TheRegion.GlobalTickTimeLocal) // TODO: 1.0 -> custom
         {
             mapLastRendered = TheRegion.GlobalTickTimeLocal;
             AABB box = new AABB() { Min = Player.GetPosition(), Max = Player.GetPosition() };
             foreach (Chunk ch in TheRegion.LoadedChunks.Values)
             {
                 box.Include(ch.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE);
                 box.Include(ch.WorldPosition.ToLocation() * Chunk.CHUNK_SIZE + new Location(Chunk.CHUNK_SIZE));
             }
             Matrix4 ortho = Matrix4.CreateOrthographicOffCenter((float)box.Min.X, (float)box.Max.X, (float)box.Min.Y, (float)box.Max.Y, (float)box.Min.Z, (float)box.Max.Z);
             //  Matrix4 oident = Matrix4.Identity;
             s_mapvox = s_mapvox.Bind();
             GL.UniformMatrix4(View3D.MAT_LOC_VIEW, false, ref ortho);
             GL.Viewport(0, 0, 256, 256); // TODO: Customizable!
             GL.BindFramebuffer(FramebufferTarget.Framebuffer, map_fbo_main);
             GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
             GL.ClearBuffer(ClearBuffer.Color, 0, new float[] { 0.0f, 1.0f, 0.0f, 1.0f });
             GL.ClearBuffer(ClearBuffer.Depth, 0, new float[] { 1.0f });
             GL.BindTexture(TextureTarget.Texture2DArray, TBlock.TextureID);
             foreach (Chunk chunk in TheRegion.LoadedChunks.Values)
             {
                 chunk.Render();
             }
             GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
             GL.BindTexture(TextureTarget.Texture2DArray, 0);
             GL.DrawBuffer(DrawBufferMode.Back);
         }
         sortEntities();
         Particles.Sort();
         MainWorldView.Headmat = TheRegion.GetBlockMaterial(PlayerEyePosition);
         MainWorldView.SunLoc = GetSunLocation();
         MainWorldView.Render();
         ReverseEntitiesOrder();
     }
     catch (Exception ex)
     {
         SysConsole.Output("Rendering (2D)", ex);
     }
     totalt.Stop();
     TotalTime = (double)totalt.ElapsedMilliseconds / 1000f;
     if (TotalTime > TotalSpikeTime)
     {
         TotalSpikeTime = TotalTime;
     }
 }
예제 #8
0
 public void PreHandleSpawn()
 {
     model = TheClient.Models.GetModel(mod);
     model.LoadSkin(TheClient.Textures);
     int ignoreme;
     if (mode == ModelCollisionMode.PRECISE)
     {
         Shape = TheClient.Models.Handler.MeshToBepu(model.Original, out ignoreme);
     }
     else if (mode == ModelCollisionMode.CONVEXHULL)
     {
         Shape = TheClient.Models.Handler.MeshToBepuConvex(model.Original, out ignoreme);
     }
     else if (mode == ModelCollisionMode.AABB)
     {
         List<BEPUutilities.Vector3> vecs = TheClient.Models.Handler.GetCollisionVertices(model.Original);
         Location zero = new Location(vecs[0]);
         AABB abox = new AABB() { Min = zero, Max = zero };
         for (int v = 1; v < vecs.Count; v++)
         {
             abox.Include(new Location(vecs[v]));
         }
         Location size = abox.Max - abox.Min;
         Location center = abox.Max - size / 2;
         Shape = new BoxShape((float)size.X * (float)scale.X, (float)size.Y * (float)scale.Y, (float)size.Z * (float)scale.Z);
         Offset = -center;
     }
     else
     {
         List<BEPUutilities.Vector3> vecs = TheClient.Models.Handler.GetCollisionVertices(model.Original);
         // Location zero = new Location(vecs[0].X, vecs[0].Y, vecs[0].Z);
         double distSq = 0;
         for (int v = 1; v < vecs.Count; v++)
         {
             if (vecs[v].LengthSquared() > distSq)
             {
                 distSq = vecs[v].LengthSquared();
             }
         }
         double size = Math.Sqrt(distSq);
         Offset = Location.Zero;
         Shape = new SphereShape((float)size * (float)scale.X);
     }
 }
예제 #9
0
 public override void Spawn()
 {
     List<BEPUutilities.Vector3> vecs = TheClient.Models.Handler.GetCollisionVertices(model.Original);
     Location zero = new Location(vecs[0]);
     AABB abox = new AABB() { Min = zero, Max = zero };
     for (int v = 1; v < vecs.Count; v++)
     {
         abox.Include(new Location(vecs[v]));
     }
     ModelMin = abox.Min.ToBVector();
     ModelMax = abox.Max.ToBVector();
 }
예제 #10
0
 public override void SpawnBody()
 {
     Model smod = TheServer.Models.GetModel(model);
     if (smod == null) // TODO: smod should return a cube when all else fails?
     {
         // TODO: Make it safe to -> TheRegion.DespawnEntity(this);
         return;
     }
     Model3D smodel = smod.Original;
     if (smodel == null) // TODO: smodel should return a cube when all else fails?
     {
         // TODO: Make it safe to -> TheRegion.DespawnEntity(this);
         return;
     }
     if (mode == ModelCollisionMode.PRECISE)
     {
         Shape = TheServer.Models.handler.MeshToBepu(smodel, out modelVerts); // TODO: Scale!
     }
     if (mode == ModelCollisionMode.CONVEXHULL)
     {
         Shape = TheServer.Models.handler.MeshToBepuConvex(smodel, out modelVerts); // TODO: Scale!
     }
     else if (mode == ModelCollisionMode.AABB)
     {
         List<BEPUutilities.Vector3> vecs = TheServer.Models.handler.GetCollisionVertices(smodel);
         Location zero = new Location(vecs[0]);
         AABB abox = new AABB() { Min = zero, Max = zero };
         for (int v = 1; v < vecs.Count; v++)
         {
             abox.Include(new Location(vecs[v]));
         }
         Location size = abox.Max - abox.Min;
         Location center = abox.Max - size / 2;
         offset = -center;
         Shape = new BoxShape((double)size.X * (double)scale.X, (double)size.Y * (double)scale.Y, (double)size.Z * (double)scale.Z);
     }
     else
     {
         List<BEPUutilities.Vector3> vecs = TheServer.Models.handler.GetCollisionVertices(smodel);
         double distSq = 0;
         for (int v = 1; v < vecs.Count; v++)
         {
             if (vecs[v].LengthSquared() > distSq)
             {
                 distSq = vecs[v].LengthSquared();
             }
         }
         double size = Math.Sqrt(distSq);
         offset = Location.Zero;
         Shape = new SphereShape((double)size * (double)scale.X);
     }
     base.SpawnBody();
     if (mode == ModelCollisionMode.PRECISE)
     {
         offset = InternalOffset;
     }
 }