private void PlaceVoxel(VoxelHandle Vox, VoxelType Type, WorldManager World) { Vox.IsPlayerBuilt = true; Vox.Type = Type; Vox.QuickSetLiquid(LiquidType.None, 0); for (int i = 0; i < 4; i++) { World.ParticleManager.Trigger("puff", MathFunctions.RandVector3Box(Vox.GetBoundingBox().Expand(0.25f)), Color.White, 5); } // Todo: Should this be handled by the chunk manager while processing voxel update events? foreach (var phys in World.EnumerateIntersectingObjects(Vox.GetBoundingBox(), CollisionType.Dynamic).OfType <Physics>()) { phys.ApplyForce((phys.GlobalTransform.Translation - (Vox.WorldPosition + new Vector3(0.5f, 0.5f, 0.5f))) * 100, 0.01f); BoundingBox box = Vox.GetBoundingBox(); Physics.Contact contact = new Physics.Contact(); Physics.TestStaticAABBAABB(box, phys.GetBoundingBox(), ref contact); if (!contact.IsIntersecting) { continue; } Vector3 diff = contact.NEnter * contact.Penetration; Matrix m = phys.LocalTransform; m.Translation += diff; phys.LocalTransform = m; } }
private void PlaceVoxel(VoxelHandle Vox, VoxelType Type, WorldManager World) { Vox.Type = Type; Vox.WaterCell = new WaterCell(); Vox.Health = Type.StartingHealth; for (int i = 0; i < 4; i++) { World.ParticleManager.Trigger("puff", MathFunctions.RandVector3Box(Vox.GetBoundingBox().Expand(0.25f)), Color.White, 5); } foreach (Physics phys in World.CollisionManager.EnumerateIntersectingObjects(Vox.GetBoundingBox(), CollisionManager.CollisionType.Dynamic).OfType <Physics>()) { phys.ApplyForce((phys.GlobalTransform.Translation - (Vox.WorldPosition + new Vector3(0.5f, 0.5f, 0.5f))) * 100, 0.01f); BoundingBox box = Vox.GetBoundingBox(); Physics.Contact contact = new Physics.Contact(); Physics.TestStaticAABBAABB(box, phys.GetBoundingBox(), ref contact); if (!contact.IsIntersecting) { continue; } Vector3 diff = contact.NEnter * contact.Penetration; Matrix m = phys.LocalTransform; m.Translation += diff; phys.LocalTransform = m; } }
public bool Collide(BoundingBox myBox, BoundingBox box) { if (!myBox.Intersects(box)) { return(false); } Physics.Contact contact = new Physics.Contact(); if (!Physics.TestStaticAABBAABB(box, box, ref contact)) { return(false); } Vector3 p = Target; p += contact.NEnter * contact.Penetration; Vector3 newVelocity = (contact.NEnter * Vector3.Dot(Velocity, contact.NEnter)); Velocity = (Velocity - newVelocity); Target = p; return(true); }
public bool Collide(VoxelHandle voxel, BoundingBox myBox, BoundingBox box) { if (!myBox.Intersects(box)) { return(false); } Physics.Contact contact = new Physics.Contact(); bool testX = !IsNeighborOccupied(voxel, -1, 0, 0) || !IsNeighborOccupied(voxel, 1, 0, 0); bool testY = !IsNeighborOccupied(voxel, 0, -1, 0) || !IsNeighborOccupied(voxel, 0, 1, 0); bool testZ = !IsNeighborOccupied(voxel, 0, 0, -1) || !IsNeighborOccupied(voxel, 0, 0, 1); if (!Physics.TestStaticAABBAABB(myBox, box, ref contact, testX, testY, testZ)) { return(false); } Vector3 p = Target; p += contact.NEnter * contact.Penetration; Velocity = Velocity - Vector3.Dot(Velocity, contact.NEnter) * contact.NEnter; Target = p; Position = Position + contact.NEnter * contact.Penetration; return(true); }
public void Put(ChunkManager manager) { VoxelChunk chunk = manager.ChunkData.ChunkMap[Vox.ChunkID]; Voxel v = chunk.MakeVoxel((int)Vox.GridPosition.X, (int)Vox.GridPosition.Y, (int)Vox.GridPosition.Z); v.Type = Type; v.Water = new WaterCell(); v.Health = Type.StartingHealth; chunk.NotifyTotalRebuild(!v.IsInterior); PlayState.ParticleManager.Trigger("puff", v.Position, Color.White, 20); List <Body> components = new List <Body>(); manager.Components.GetBodiesIntersecting(Vox.GetBoundingBox(), components, CollisionManager.CollisionType.Dynamic); foreach (Physics phys in components.OfType <Physics>()) { phys.ApplyForce((phys.GlobalTransform.Translation - (Vox.Position + new Vector3(0.5f, 0.5f, 0.5f))) * 100, 0.01f); BoundingBox box = v.GetBoundingBox(); Physics.Contact contact = new Physics.Contact(); Physics.TestStaticAABBAABB(box, phys.GetBoundingBox(), ref contact); if (!contact.IsIntersecting) { continue; } Vector3 diff = contact.NEnter * contact.Penetration; Matrix m = phys.LocalTransform; m.Translation += diff; phys.LocalTransform = m; } }
public void Update(ParticleManager manager, DwarfTime gameTime, ChunkManager chunks, Camera camera) { ParticleEmitter._camera = camera; List <Particle> toRemove = new List <Particle>(); TriggerTimer.Update(gameTime); if (TriggerTimer.HasTriggered && Data.ParticlesPerFrame > 0) { Trigger(Data.ParticlesPerFrame, Vector3.Zero, new Color(255, 255, 0)); } bool particlePhysics = GameSettings.Default.ParticlePhysics; foreach (Particle p in Particles) { float vel = p.Velocity.LengthSquared(); if (Data.EmitsLight && p.Scale > 0.1f) { DynamicLight.TempLights.Add(new DynamicLight(10.0f, 255.0f, false) { Position = p.Position }); } p.Position += p.Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds; if (Data.RotatesWithVelocity) { Vector3 cameraVel = camera.Project(p.Velocity + camera.Position); float projectionX = cameraVel.X; float projectionY = cameraVel.Y; p.Angle = (float)Math.Atan2(projectionY, projectionX); } else { p.Angle += (float)(p.AngularVelocity * gameTime.ElapsedGameTime.TotalSeconds); } if (!Data.Sleeps || vel > 0.01f) { p.Velocity += Data.ConstantAccel * (float)gameTime.ElapsedGameTime.TotalSeconds; } p.Velocity *= Data.LinearDamping; p.AngularVelocity *= Data.AngularDamping; if (!Data.UseManualControl) { p.LifeRemaining -= Data.ParticleDecay * (float)gameTime.ElapsedGameTime.TotalSeconds; } else if (p.TimeAlive > 60) { p.LifeRemaining = 0; } p.Scale += Data.GrowthSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds; p.Scale = Math.Max(p.Scale, 0.0f); var v = new VoxelHandle(chunks.ChunkData, GlobalVoxelCoordinate.FromVector3(p.Position)); if (Data.HasLighting) { if (v.IsValid) { p.LightRamp = new Color(v.Sunlight ? 255 : 0, 255, 0); } } else { p.LightRamp = new Color(255, 255, 0); } if (Data.CollidesWorld && particlePhysics && vel > 0.2f) { if (v.IsValid && !v.IsEmpty) { BoundingBox b = new BoundingBox(p.Position - Vector3.One * p.Scale * 0.5f, p.Position + Vector3.One * p.Scale * 0.5f); BoundingBox vBox = v.GetBoundingBox(); Physics.Contact contact = new Physics.Contact(); if (Physics.TestStaticAABBAABB(b, vBox, ref contact)) { p.Position += contact.NEnter * contact.Penetration; Vector3 newVelocity = Vector3.Reflect(p.Velocity, -contact.NEnter); p.Velocity = newVelocity * Data.Damping; p.AngularVelocity *= 0.5f; if (Data.Sleeps) { p.Velocity = Vector3.Zero; p.AngularVelocity = 0.0f; vel = 0.0f; } if (!String.IsNullOrEmpty(Data.SpatterType)) { var above = VoxelHelpers.GetVoxelAbove(v); if (!above.IsValid || above.IsEmpty) { float x = MathFunctions.Clamp(p.Position.X, vBox.Min.X + 0.1f, vBox.Max.X - 0.1f); float z = MathFunctions.Clamp(p.Position.Z, vBox.Min.Z + 0.1f, vBox.Max.Z - 0.1f); manager.Create(Data.SpatterType, VertexNoise.Warp(new Vector3(x, v.RampType == RampType.None ? v.WorldPosition.Y + 1.02f : v.WorldPosition.Y + 0.6f, z)), Vector3.Zero, Color.White, Vector3.Up); } else { manager.Create(Data.SpatterType, p.Position - contact.NEnter * contact.Penetration * 0.95f, Vector3.Zero, Color.White, contact.NEnter); } p.LifeRemaining = -1.0f; } } } } if (p.LifeRemaining < 0) { if (p.InstanceData != null) { p.InstanceData.ShouldDraw = false; p.InstanceData.Transform = Matrix.CreateTranslation(camera.Position + new Vector3(-1000, -1000, -1000)); Sprites[p.Frame].Remove(p.InstanceData); } toRemove.Add(p); } else if (p.InstanceData != null) { p.TimeAlive += (float)gameTime.ElapsedGameTime.TotalSeconds + MathFunctions.Rand() * 0.01f; int prevFrame = p.Frame; int newFrame = AnimPlayer.GetFrame(p.TimeAlive); if (vel < 0.2f) { newFrame = prevFrame; } if (newFrame != prevFrame) { p.Frame = newFrame; if (Sprites.Count > 0) { Sprites[prevFrame].Remove(p.InstanceData); Sprites[newFrame].Add(p.InstanceData); } if (/*!Data.Animation.Loops && */ p.Frame == Data.Animation.Frames.Count - 1) { p.LifeRemaining *= 0.1f; } } p.InstanceData.ShouldDraw = true; p.InstanceData.Transform = MatrixFromParticle(Data, p); p.InstanceData.LightRamp = p.LightRamp; } } foreach (Particle p in toRemove) { Particles.Remove(p); } foreach (var sprites in Sprites) { sprites.Update(gameTime, camera, GameState.Game.GraphicsDevice, chunks.World.Master.MaxViewingLevel); } }
public override void Update(DwarfTime gameTime, ChunkManager chunks, Camera camera) { ParticleEmitter._camera = camera; List <Particle> toRemove = new List <Particle>(); TriggerTimer.Update(gameTime); if (TriggerTimer.HasTriggered && Data.ParticlesPerFrame > 0) { Trigger(Data.ParticlesPerFrame, Vector3.Zero, Tint); } bool particlePhysics = GameSettings.Default.ParticlePhysics; foreach (Particle p in Particles) { float vel = p.Velocity.LengthSquared(); if (!Data.Sleeps || vel > 0.2f) { if (Data.EmitsLight && p.Scale > 0.1f) { DynamicLight.TempLights.Add(new DynamicLight(10.0f, 255.0f, false) { Position = p.Position }); } p.Position += p.Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds; if (Data.RotatesWithVelocity) { Vector3 cameraVel = camera.Project(p.Velocity + camera.Position); float projectionX = cameraVel.X; float projectionY = cameraVel.Y; p.Angle = (float)Math.Atan2(projectionY, projectionX); } else { p.Angle += (float)(p.AngularVelocity * gameTime.ElapsedGameTime.TotalSeconds); } p.Velocity += Data.ConstantAccel * (float)gameTime.ElapsedGameTime.TotalSeconds; p.Velocity *= Data.LinearDamping; p.AngularVelocity *= Data.AngularDamping; } else if (Data.Sleeps && vel < 0.2f) { p.Velocity = Vector3.Zero; } if (!Data.UseManualControl) { p.LifeRemaining -= Data.ParticleDecay * (float)gameTime.ElapsedGameTime.TotalSeconds; } p.Scale += Data.GrowthSpeed * (float)gameTime.ElapsedGameTime.TotalSeconds; p.Scale = Math.Max(p.Scale, 0.0f); var v = new VoxelHandle(chunks.ChunkData, GlobalVoxelCoordinate.FromVector3(p.Position)); if (Data.HasLighting) { if (v.IsValid && v.IsEmpty) { p.Tint = new Color(v.SunColor, 255, 0); } } if (Data.CollidesWorld && particlePhysics && vel > 0.2f) { BoundingBox b = new BoundingBox(p.Position - Vector3.One * p.Scale * 0.5f, p.Position + Vector3.One * p.Scale * 0.5f); if (v.IsValid && !v.IsEmpty) { Physics.Contact contact = new Physics.Contact(); if (Physics.TestStaticAABBAABB(b, v.GetBoundingBox(), ref contact)) { p.Position += contact.NEnter * contact.Penetration; Vector3 newVelocity = Vector3.Reflect(p.Velocity, -contact.NEnter); p.Velocity = newVelocity * Data.Damping; p.AngularVelocity *= 0.5f; } } } if (p.LifeRemaining < 0) { if (p.InstanceData != null) { p.InstanceData.ShouldDraw = false; p.InstanceData.Transform = Matrix.CreateTranslation(camera.Position + new Vector3(-1000, -1000, -1000)); Sprites[p.Frame].Remove(p.InstanceData); } toRemove.Add(p); } else if (p.InstanceData != null) { p.TimeAlive += (float)gameTime.ElapsedGameTime.TotalSeconds + MathFunctions.Rand() * 0.01f; int prevFrame = p.Frame; int newFrame = AnimPlayer.GetFrame(p.TimeAlive); if (newFrame != prevFrame) { p.Frame = newFrame; if (Sprites.Count > 0) { Sprites[prevFrame].Remove(p.InstanceData); Sprites[newFrame].Add(p.InstanceData); } if (/*!Data.Animation.Loops && */ p.Frame == Data.Animation.Frames.Count - 1) { p.LifeRemaining *= 0.1f; } } p.InstanceData.ShouldDraw = true; p.InstanceData.Transform = MatrixFromParticle(p); p.InstanceData.Color = p.Tint; } } foreach (Particle p in toRemove) { Particles.Remove(p); } foreach (var sprites in Sprites) { sprites.Update(gameTime, camera, chunks.Graphics, chunks.ChunkData.MaxViewingLevel); } if (Particles.Count > 0) { base.Update(gameTime, chunks, camera); } }