public override void Initialize() { // Compute the Eye position into the entity _entityEyeOffset = new Vector3(0, Player.DefaultSize.Y / 100 * 80, 0); // Set Position // Set the entity world position following the position received from server _worldPosition = Player.Position; // Compute the initial Player world bounding box VisualVoxelEntity.RefreshWorldBoundingBox(ref _worldPosition); // Init Velret physic simulator _physicSimu = new VerletSimulator(ref VisualVoxelEntity.LocalBBox) { WithCollisionBouncing = false }; _physicSimu.ConstraintFct += _entityCollisionManager.IsCollidingWithEntity; //Check against entities first _physicSimu.ConstraintFct += _landscapeManager.IsCollidingWithTerrain; //Landscape checking after _entityRotations = new EntityRotations(_inputsManager, _physicSimu); _entityRotations.EntityRotationSpeed = Player.RotationSpeed; _entityRotations.SetOrientation(Player.HeadRotation, _worldPosition + _entityEyeOffset); // Set displacement mode _playerCharacter.DisplacementMode = Player.DisplacementMode; }
public void Start() { switch (simulationMode) { case SimulationMode.Verlet: verletSimulator = new VerletSimulator(ref verletConstants) { simulationManager = this, targetManager = TargetManager, particleDisplayer = Displayer }; verletSimulator.Start(); break; case SimulationMode.Euler: eulerSimulator = new EulerSimulator(ref eulerConstants) { simulationManager = this, targetManager = TargetManager, particleDisplayer = Displayer }; eulerSimulator.Start(); break; } // Call this from here to make sure all the required variables are set Displayer.SpawnParticles(); }
void Start() { debuggers = new List <GameObject>(); particles = new List <VParticle>(); for (int i = 0; i < count; i++) { var p = new VParticle(Vector3.right * i); particles.Add(p); var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere.transform.localScale = Vector3.one * 0.25f; debuggers.Add(sphere); } ; for (int i = 0; i < count; i++) { if (i != count - 1) { var a = particles[i]; var b = particles[i + 1]; var e = new VEdge(a, b); a.Connect(e); b.Connect(e); } } simulator = new VerletSimulator(particles); }
private static bool IsSlopeCollisionDetection(VerletSimulator physicSimu, VisualEntity entityTesting, ref BoundingBox playerBoundingBox, ref BoundingBox playerBoundingBox2Evaluate, ref Vector3D newPosition2Evaluate, ref Vector3D previousPosition, ItemOrientation slopeOrientation, bool onSlidingSlope, out bool isSliding) { isSliding = false; Vector3 entityPosition = newPosition2Evaluate.AsVector3(); float posi = 0.0f; float L = 0.0f; float H = entityTesting.WorldBBox.Maximum.Y - entityTesting.WorldBBox.Minimum.Y; switch (slopeOrientation) { case ItemOrientation.North: L = entityTesting.WorldBBox.Maximum.Z - entityTesting.WorldBBox.Minimum.Z; posi = (entityPosition.Z + playerBoundingBox.Maximum.Z) - entityTesting.WorldBBox.Minimum.Z; break; case ItemOrientation.South: L = entityTesting.WorldBBox.Maximum.Z - entityTesting.WorldBBox.Minimum.Z; posi = entityTesting.WorldBBox.Maximum.Z - (entityPosition.Z + playerBoundingBox.Minimum.Z); break; case ItemOrientation.East: L = entityTesting.WorldBBox.Maximum.X - entityTesting.WorldBBox.Minimum.X; posi = entityTesting.WorldBBox.Maximum.X - (entityPosition.X + playerBoundingBox.Minimum.X); break; case ItemOrientation.West: L = entityTesting.WorldBBox.Maximum.X - entityTesting.WorldBBox.Minimum.X; posi = (entityPosition.X + playerBoundingBox.Maximum.X) - entityTesting.WorldBBox.Minimum.X; break; default: break; } float posiOriginal = posi; posi = posi / L; float Y = posi * H; Y = Math.Min(Math.Max(Y, 0), 1); if (onSlidingSlope) { return(SlidingSlope(physicSimu, entityTesting, Y, ref newPosition2Evaluate, ref previousPosition, slopeOrientation, out isSliding)); } //Apply only if new Y is >= Current Y if (entityTesting.WorldBBox.Minimum.Y + Y > newPosition2Evaluate.Y) { return(NormalSlope(physicSimu, entityTesting, Y, ref newPosition2Evaluate, ref previousPosition)); } else { physicSimu.AllowJumping = true; return(false); } }
//Entity vs Player Collision detection //Used by physics engine public void IsCollidingWithEntity(VerletSimulator physicSimu, ref BoundingBox playerBoundingBox, ref Vector3D newPosition2Evaluate, ref Vector3D previousPosition, ref Vector3D originalPosition) { if (IsDirty) { _timer_OnTimerRaised(); } IsCollidingWithEntity(physicSimu, AroundEntities(), ref playerBoundingBox, ref newPosition2Evaluate, ref previousPosition, ref originalPosition); }
public void Update(DynamicUpdateState gameTime) { var elapsedS = (float)gameTime.RealTime.TotalSeconds; Vector3D newPos; VerletSimulator.Simulate(elapsedS, out newPos); Npc.DynamicEntity.Position = newPos; VerletSimulator.CurPosition = Npc.DynamicEntity.Position; if (IsMoving) { if (Vector3D.DistanceSquared(_pathTargetPoint, Npc.DynamicEntity.Position) < 0.1d) { FollowNextPoint(); } _moveDirection = _pathTargetPoint - Npc.DynamicEntity.Position; _jump = _moveDirection.Y > 0; _moveDirection.Y = 0; //if (Vector3D.DistanceSquared(VerletSimulator.PrevPosition, VerletSimulator.CurPosition) < 0.01f) //{ // if (Math.Abs(_moveDirection.X) < Math.Abs(_moveDirection.Z)) // _moveDirection.Z = 0.1f * Math.Sign(_moveDirection.Z); // else // _moveDirection.X = 0.1f * Math.Sign(_moveDirection.X); //} _moveDirection.Normalize(); VerletSimulator.Impulses.Add(new Impulse(elapsedS) { ForceApplied = _moveDirection.AsVector3() * Npc.DynamicEntity.MoveSpeed * (_runAway ? 2f : 1f) }); if (_jump && VerletSimulator.OnGround) { VerletSimulator.Impulses.Add(new Impulse(elapsedS) { ForceApplied = Vector3.UnitY * 22 }); } } if (_leader != null && Vector3D.Distance(_leader.Position, Npc.DynamicEntity.Position) > FollowStayDistance) { if (IsMoving && Vector3D.Distance(new Vector3D(_path.Goal) + CubeCenter, _leader.Position) < FollowStayDistance) { return; } MoveTo(_leader.Position.ToCubePosition()); } }
void Start() { debuggers = new List <GameObject>(); particles = new List <Node>(); var offset = -count * 0.5f; for (int y = 0; y < count; y++) { for (int x = 0; x < count; x++) { var p = new Node(y * Vector3.forward + (Vector3.right * (x - offset))); particles.Add(p); var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere.transform.localScale = Vector3.one * 0.25f; debuggers.Add(sphere); } } for (int y = 0; y < count; y++) { if (y != count - 1) { for (int x = 0; x < count; x++) { var index = y * count + x; var c = particles[index]; if (x != count - 1) { var right = particles[index + 1]; var re = new Edge(c, right); c.Connect(re); right.Connect(re); } var down = particles[index + count]; var de = new Edge(c, down); c.Connect(de); down.Connect(de); } } else { for (int x = 0; x < count - 1; x++) { var index = y * count + x; var c = particles[index]; var right = particles[index + 1]; var re = new Edge(c, right); c.Connect(re); right.Connect(re); } } } simulator = new VerletSimulator(particles); }
private static bool NormalSlope(VerletSimulator physicSimu, VisualEntity entityTesting, float Y, ref Vector3D newPosition2Evaluate, ref Vector3D previousPosition) { if (((entityTesting.WorldBBox.Minimum.Y + Y) - newPosition2Evaluate.Y) < 0.3f) { //Push up the player, and stabilize its physic simulation newPosition2Evaluate.Y = entityTesting.WorldBBox.Minimum.Y + Y; previousPosition.Y = newPosition2Evaluate.Y; physicSimu.OnGround = true; physicSimu.AllowJumping = true; return(false); } else { return(true); } }
public MoveAI(ServerNpc parentNpc) { _parentNpc = parentNpc; var size = parentNpc.DynamicEntity.DefaultSize; var bb = new BoundingBox(Vector3.Zero, size); size.Y = 0; bb = bb.Offset(-size / 2); VerletSimulator = new VerletSimulator(ref bb); VerletSimulator.ConstraintFct += Npc.Server.LandscapeManager.IsCollidingWithTerrain; VerletSimulator.StartSimulation(parentNpc.DynamicEntity.Position); FollowKeepDistance = 3; FollowStayDistance = 5; }
public static void IsCollidingWithEntity(VerletSimulator physicSimu, IEnumerable <VisualEntity> aroundEntities, ref BoundingBox playerBoundingBox, ref Vector3D newPosition2Evaluate, ref Vector3D previousPosition, ref Vector3D originalPosition) { bool isSliding = false; foreach (var entityTesting in aroundEntities) { if (!entityTesting.Entity.IsPlayerCollidable) { continue; } //Compute the New world located player bounding box, that will be use for collision detection var playerBoundingBox2Evaluate = new BoundingBox(playerBoundingBox.Minimum + newPosition2Evaluate.AsVector3(), playerBoundingBox.Maximum + newPosition2Evaluate.AsVector3()); bool isEntityOnSliding; CollisionCheck(physicSimu, entityTesting, ref playerBoundingBox, ref playerBoundingBox2Evaluate, ref newPosition2Evaluate, ref previousPosition, out isEntityOnSliding); isSliding |= isEntityOnSliding; } physicSimu.IsSliding = isSliding; }
void Start() { vcam = FindObjectOfType <CinemachineVirtualCamera>(); particles = new List <Node>(); for (int i = 0; i < 10; i++) { var p = new Node(Vector3.down * i, Joints[i]); particles.Add(p); Joints[i].SetLimb(i); } ; particles[(int)LimbsEnum.Hips].lockInGrip = true; particles[(int)LimbsEnum.Hips].lockPosition = particles[(int)LimbsEnum.Hips].model.transform.position; ConnectHumanJoints(); startPoint = Joints[(int)LimbsEnum.Hips].transform.position.y; SetHeight(); simulator = new VerletSimulator(particles); simulator.freezeZ = FreezZ; PreviewEnergy(); InfoMessageText = "Go Up"; StartCoroutine(InfoMessageDisplay()); }
private static void CollisionCheck(VerletSimulator physicSimu, VisualEntity entityTesting, ref BoundingBox entityBoundingBox, ref BoundingBox boundingBox2Evaluate, ref Vector3D newPosition2Evaluate, ref Vector3D previousPosition, out bool isSliding) { isSliding = false; if (entityTesting.WorldBBox.Intersects(ref boundingBox2Evaluate)) { if (entityTesting.Entity is Ladder) { physicSimu.isInContactWithLadder = true; return; } //Special treatment in case of an IOrientedSlope entity if (entityTesting.Entity is IOrientedSlope) { IOrientedSlope entity = (IOrientedSlope)entityTesting.Entity; if (entity.IsOrientedSlope) { SlopeCollisionDetection(physicSimu, entityTesting, ref entityBoundingBox, ref boundingBox2Evaluate, ref newPosition2Evaluate, ref previousPosition, entity.Orientation, entity.IsSlidingSlope, out isSliding); return; } } switch (entityTesting.Entity.CollisionType) { case Utopia.Shared.Entities.Entity.EntityCollisionType.BoundingBox: BoundingBoxCollision(physicSimu, entityTesting, ref entityBoundingBox, ref boundingBox2Evaluate, ref newPosition2Evaluate, ref previousPosition); break; case Utopia.Shared.Entities.Entity.EntityCollisionType.Model: ModelCollisionDetection(physicSimu, entityTesting, ref entityBoundingBox, ref boundingBox2Evaluate, ref newPosition2Evaluate, ref previousPosition); break; default: break; } } }
private static void SlopeCollisionDetection(VerletSimulator physicSimu, VisualEntity entityTesting, ref BoundingBox playerBoundingBox, ref BoundingBox playerBoundingBox2Evaluate, ref Vector3D newPosition2Evaluate, ref Vector3D previousPosition, ItemOrientation slopeOrientation, bool OnSlidingSlope, out bool isSliding) { if (IsSlopeCollisionDetection(physicSimu, entityTesting, ref playerBoundingBox, ref playerBoundingBox2Evaluate, ref newPosition2Evaluate, ref previousPosition, slopeOrientation, OnSlidingSlope, out isSliding)) { Vector3D newPositionWithColliding = previousPosition; newPositionWithColliding.X = newPosition2Evaluate.X; playerBoundingBox2Evaluate = new BoundingBox(playerBoundingBox.Minimum + newPositionWithColliding.AsVector3(), playerBoundingBox.Maximum + newPositionWithColliding.AsVector3()); if (entityTesting.WorldBBox.Intersects(ref playerBoundingBox2Evaluate)) { newPositionWithColliding.X = previousPosition.X; } newPositionWithColliding.Z = newPosition2Evaluate.Z; playerBoundingBox2Evaluate = new BoundingBox(playerBoundingBox.Minimum + newPositionWithColliding.AsVector3(), playerBoundingBox.Maximum + newPositionWithColliding.AsVector3()); if (entityTesting.WorldBBox.Intersects(ref playerBoundingBox2Evaluate)) { newPositionWithColliding.Z = previousPosition.Z; } newPosition2Evaluate = newPositionWithColliding; } }
private static void BoundingBoxCollision(VerletSimulator physicSimu, VisualEntity entityTesting, ref BoundingBox entityBoundingBox, ref BoundingBox boundingBox2Evaluate, ref Vector3D newPosition2Evaluate, ref Vector3D previousPosition) { Vector3D newPositionWithColliding = previousPosition; newPositionWithColliding.Y = newPosition2Evaluate.Y; boundingBox2Evaluate = new BoundingBox(entityBoundingBox.Minimum + newPositionWithColliding.AsVector3(), entityBoundingBox.Maximum + newPositionWithColliding.AsVector3()); if (entityTesting.WorldBBox.Intersects(ref boundingBox2Evaluate)) { //If falling if (newPositionWithColliding.Y <= previousPosition.Y) { newPositionWithColliding.Y = entityTesting.WorldBBox.Maximum.Y; //previousPosition.Y; } else { newPositionWithColliding.Y = previousPosition.Y; } previousPosition.Y = newPositionWithColliding.Y; _onEntityTop = true; } newPositionWithColliding.X = newPosition2Evaluate.X; boundingBox2Evaluate = new BoundingBox(entityBoundingBox.Minimum + newPositionWithColliding.AsVector3(), entityBoundingBox.Maximum + newPositionWithColliding.AsVector3()); if (entityTesting.WorldBBox.Intersects(ref boundingBox2Evaluate, 0.001f)) { newPositionWithColliding.X = previousPosition.X; _onEntityTop = false; } newPositionWithColliding.Z = newPosition2Evaluate.Z; boundingBox2Evaluate = new BoundingBox(entityBoundingBox.Minimum + newPositionWithColliding.AsVector3(), entityBoundingBox.Maximum + newPositionWithColliding.AsVector3()); if (entityTesting.WorldBBox.Intersects(ref boundingBox2Evaluate, 0.001f)) { newPositionWithColliding.Z = previousPosition.Z; _onEntityTop = false; } //Set the NEW player position after collision tests newPosition2Evaluate = newPositionWithColliding; // ? Am I on "TOP" of an object ??? if (_onEntityTop == true) { physicSimu.OnGround = true; } if (entityTesting.Entity is IDynamicEntity) { //Send an impulse message to the Entity, following my "LookAtVector" ! float impulsePower = 1; if (_input.ActionsManager.isTriggered(UtopiaActions.Move_Run)) { impulsePower = 2; } _server.ServerConnection.Send(new EntityImpulseMessage { DynamicEntityId = (entityTesting.Entity as IDynamicEntity).DynamicId, Vector3 = MQuaternion.GetLookAtFromQuaternion(_player.Player.HeadRotation) * impulsePower } ); } }
private static bool SlidingSlope(VerletSimulator physicSimu, VisualEntity entityTesting, float Y, ref Vector3D newPosition2Evaluate, ref Vector3D previousPosition, ItemOrientation slopeOrientation, out bool isSliding) { isSliding = false; if (entityTesting.WorldBBox.Minimum.Y + Y >= newPosition2Evaluate.Y) { if (((entityTesting.WorldBBox.Minimum.Y + Y) - newPosition2Evaluate.Y) < 0.3f) { Y = Y - (float)(newPosition2Evaluate.Y - Math.Floor(newPosition2Evaluate.Y)); if (Y < 0.001 || Y >= 0.999) { Y = 0.02f; } newPosition2Evaluate.Y += entityTesting.Entity.Friction; isSliding = true; switch (slopeOrientation) { case ItemOrientation.North: newPosition2Evaluate.Z = newPosition2Evaluate.Z - Y; if (physicSimu.IsSliding == false) { physicSimu.SliddingForce = new Vector3(0, 0, -1); } break; case ItemOrientation.South: newPosition2Evaluate.Z = newPosition2Evaluate.Z + Y; if (physicSimu.IsSliding == false) { physicSimu.SliddingForce = new Vector3(0, 0, 1); } break; case ItemOrientation.East: newPosition2Evaluate.X = newPosition2Evaluate.X + Y; if (physicSimu.IsSliding == false) { physicSimu.SliddingForce = new Vector3(1, 0, 0); } break; case ItemOrientation.West: newPosition2Evaluate.X = newPosition2Evaluate.X - Y; if (physicSimu.IsSliding == false) { physicSimu.SliddingForce = new Vector3(-1, 0, 0); } break; default: break; } return(false); } else { return(true); } } else { physicSimu.AllowJumping = true; return(false); } }
private static void ModelCollisionDetection(VerletSimulator physicSimu, VisualEntity entityTesting, ref BoundingBox playerBoundingBox, ref BoundingBox playerBoundingBox2Evaluate, ref Vector3D newPosition2Evaluate, ref Vector3D previousPosition) { if (entityTesting.SkipOneCollisionTest) { entityTesting.SkipOneCollisionTest = false; return; } Vector3D newPositionWithColliding = previousPosition; _onEntityTop = null; newPositionWithColliding.X = newPosition2Evaluate.X; playerBoundingBox2Evaluate = new BoundingBox(playerBoundingBox.Minimum + newPositionWithColliding.AsVector3(), playerBoundingBox.Maximum + newPositionWithColliding.AsVector3()); if (IsCollidingWithModel(entityTesting, playerBoundingBox2Evaluate)) { //logger.Debug("ModelCollisionDetection X detected tested {0}, assigned (= previous) {1}", newPositionWithColliding.X, previousPosition.X); newPositionWithColliding.X = previousPosition.X; _onEntityTop = false; Player.YForceApplying = entityTesting.Entity.YForceOnSideHit; } newPositionWithColliding.Z = newPosition2Evaluate.Z; playerBoundingBox2Evaluate = new BoundingBox(playerBoundingBox.Minimum + newPositionWithColliding.AsVector3(), playerBoundingBox.Maximum + newPositionWithColliding.AsVector3()); if (IsCollidingWithModel(entityTesting, playerBoundingBox2Evaluate)) { //logger.Debug("ModelCollisionDetection Z detected tested {0}, assigned (= previous) {1}", newPositionWithColliding.Z, previousPosition.Z); newPositionWithColliding.Z = previousPosition.Z; _onEntityTop = false; Player.YForceApplying = entityTesting.Entity.YForceOnSideHit; } newPositionWithColliding.Y = newPosition2Evaluate.Y; playerBoundingBox2Evaluate = new BoundingBox(playerBoundingBox.Minimum + newPositionWithColliding.AsVector3(), playerBoundingBox.Maximum + newPositionWithColliding.AsVector3()); if (IsCollidingWithModel(entityTesting, playerBoundingBox2Evaluate)) { //logger.Debug("ModelCollisionDetection Y detected tested {0}, assigned (= previous) {1}", newPositionWithColliding.Y, previousPosition.Y); newPositionWithColliding.Y = previousPosition.Y; if (_onEntityTop == null) { _onEntityTop = true; } } else { if (_isOnGround) { playerBoundingBox2Evaluate.Minimum.Y -= 0.01f; if (IsCollidingWithModel(entityTesting, playerBoundingBox2Evaluate)) { _onEntityTop = true; } } } //Set the NEW player position after collision tests newPosition2Evaluate = newPositionWithColliding; if (_onEntityTop == true) { physicSimu.OnGround = true; _isOnGround = true; physicSimu.AllowJumping = true; } else { _isOnGround = false; } playerBoundingBox2Evaluate = new BoundingBox(playerBoundingBox.Minimum + newPositionWithColliding.AsVector3(), playerBoundingBox.Maximum + newPositionWithColliding.AsVector3()); if (_onEntityTop != true && IsCollidingWithModel(entityTesting, playerBoundingBox2Evaluate)) { //I'm "Blocked" by this entity ! //Testing, inject Force to unblock myself ! var forceDirection = playerBoundingBox2Evaluate.GetCenter() - entityTesting.WorldBBox.GetCenter(); forceDirection.Normalize(); physicSimu.Impulses.Add(new Impulse { ForceApplied = forceDirection * 3 }); entityTesting.SkipOneCollisionTest = true; } }
/// <summary> /// Validate player move against surrounding landscape, if move not possible, it will be "rollbacked" /// It's used by the physic engine /// </summary> /// <param name="physicSimu"></param> /// <param name="localEntityBoundingBox"></param> /// <param name="newPosition2Evaluate"></param> /// <param name="previousPosition"></param> /// <param name="originalPosition"></param> public void IsCollidingWithTerrain(VerletSimulator physicSimu, ref BoundingBox localEntityBoundingBox, ref Vector3D newPosition2Evaluate, ref Vector3D previousPosition, ref Vector3D originalPosition) { Vector3D newPositionWithColliding = previousPosition; TerraCubeWithPosition collidingCube; //Create a Bounding box with my new suggested position, taking only the X that has been changed ! //X Testing ===================================================== newPositionWithColliding.X = newPosition2Evaluate.X; BoundingBox boundingBox2Evaluate = new BoundingBox(localEntityBoundingBox.Minimum + newPositionWithColliding.AsVector3(), localEntityBoundingBox.Maximum + newPositionWithColliding.AsVector3()); //If my new X position, make me placed "inside" a block, then invalid the new position if (IsSolidToPlayer(ref boundingBox2Evaluate, true, out collidingCube)) { //logger.Debug("ModelCollisionDetection X detected tested {0}, assigned (= previous) {1}", newPositionWithColliding.X, previousPosition.X); newPositionWithColliding.X = previousPosition.X; if (collidingCube.BlockProfile.YBlockOffset > 0 || physicSimu.OnOffsettedBlock > 0) { float offsetValue = (float)((1 - collidingCube.BlockProfile.YBlockOffset)); if (physicSimu.OnOffsettedBlock > 0) { offsetValue -= (1 - physicSimu.OnOffsettedBlock); } if (offsetValue <= 0.5) { if (collidingCube.BlockProfile.YBlockOffset == 0 && collidingCube.Position.Y + 1 < AbstractChunk.ChunkSize.Y) { //Check if an other block is place over the hitted one var overcube = GetCubeAt(new Vector3I(collidingCube.Position.X, collidingCube.Position.Y + 1, collidingCube.Position.Z)); if (overcube.Id == WorldConfiguration.CubeId.Air) { physicSimu.OffsetBlockHitted = offsetValue; } } else { physicSimu.OffsetBlockHitted = offsetValue; } } } } //Z Testing ========================================================= newPositionWithColliding.Z = newPosition2Evaluate.Z; boundingBox2Evaluate = new BoundingBox(localEntityBoundingBox.Minimum + newPositionWithColliding.AsVector3(), localEntityBoundingBox.Maximum + newPositionWithColliding.AsVector3()); //If my new Z position, make me placed "inside" a block, then invalid the new position if (IsSolidToPlayer(ref boundingBox2Evaluate, true, out collidingCube)) { //logger.Debug("ModelCollisionDetection Z detected tested {0}, assigned (= previous) {1}", newPositionWithColliding.Z, previousPosition.Z); newPositionWithColliding.Z = previousPosition.Z; if (collidingCube.BlockProfile.YBlockOffset > 0 || physicSimu.OnOffsettedBlock > 0) { float offsetValue = (float)((1 - collidingCube.BlockProfile.YBlockOffset)); if (physicSimu.OnOffsettedBlock > 0) { offsetValue -= (1 - physicSimu.OnOffsettedBlock); } if (offsetValue <= 0.5) { if (collidingCube.BlockProfile.YBlockOffset == 0 && collidingCube.Position.Y + 1 < AbstractChunk.ChunkSize.Y) { //Check if an other block is place over the hitted one var overcube = GetCubeAt(new Vector3I(collidingCube.Position.X, collidingCube.Position.Y + 1, collidingCube.Position.Z)); if (overcube.Id == WorldConfiguration.CubeId.Air) { physicSimu.OffsetBlockHitted = offsetValue; } } else { physicSimu.OffsetBlockHitted = offsetValue; } } } } //Y Testing ====================================================== newPositionWithColliding.Y = newPosition2Evaluate.Y; boundingBox2Evaluate = new BoundingBox(localEntityBoundingBox.Minimum + newPositionWithColliding.AsVector3(), localEntityBoundingBox.Maximum + newPositionWithColliding.AsVector3()); //If my new Y position, make me placed "inside" a block, then invalid the new position if (IsSolidToPlayer(ref boundingBox2Evaluate, true, out collidingCube)) { //If was Jummping "before" entering inside the cube if (previousPosition.Y >= newPositionWithColliding.Y) { //If the movement between 2 Y is too large, use the GroundBelowEntity value if (Math.Abs(newPositionWithColliding.Y - previousPosition.Y) > 1 || physicSimu.isInContactWithLadder) { previousPosition.Y = physicSimu.GroundBelowEntity; } else { //Raise Up until the Ground, next the previous position if (collidingCube.BlockProfile.YBlockOffset > 0) { previousPosition.Y = MathHelper.Floor(previousPosition.Y + 1) - collidingCube.BlockProfile.YBlockOffset; } else { previousPosition.Y = MathHelper.Floor(originalPosition.Y); } } physicSimu.OffsetBlockHitted = 0; physicSimu.OnGround = true; // On ground ==> Activite the force that will counter the gravity !! } //logger.Debug("ModelCollisionDetection Y detected tested {0}, assigned (= previous) {1}", newPositionWithColliding.Y, previousPosition.Y); newPositionWithColliding.Y = previousPosition.Y; } else { //No collision with Y, is the block below me solid to entity ? boundingBox2Evaluate.Minimum.Y -= 0.01f; if (IsSolidToPlayer(ref boundingBox2Evaluate, true, out collidingCube)) { physicSimu.OnGround = true; // On ground ==> Activite the force that will counter the gravity !! } } //Check to see if new destination is not blocking me boundingBox2Evaluate = new BoundingBox(localEntityBoundingBox.Minimum + newPositionWithColliding.AsVector3(), localEntityBoundingBox.Maximum + newPositionWithColliding.AsVector3()); if (IsSolidToPlayer(ref boundingBox2Evaluate, true, out collidingCube)) { //logger.Debug("Block STUCK tested {0}, assigned {1}", newPositionWithColliding, previousPosition); newPositionWithColliding = originalPosition; newPositionWithColliding.Y += 0.1; } newPosition2Evaluate = newPositionWithColliding; }
public EntityRotations(InputsManager inputManager, VerletSimulator physicSimu) { _inputsManager = inputManager; _physicSimu = physicSimu; }