use of org.terasology.physics.HitResult in project Terasology by MovingBlocks.
the class PhysicsSystem method update.
@Override
public void update(float delta) {
PerformanceMonitor.startActivity("Physics Renderer");
physics.update(time.getGameDelta());
PerformanceMonitor.endActivity();
// Update the velocity from physics engine bodies to Components:
Iterator<EntityRef> iter = physics.physicsEntitiesIterator();
while (iter.hasNext()) {
EntityRef entity = iter.next();
RigidBodyComponent comp = entity.getComponent(RigidBodyComponent.class);
RigidBody body = physics.getRigidBody(entity);
if (body.isActive()) {
body.getLinearVelocity(comp.velocity);
body.getAngularVelocity(comp.angularVelocity);
Vector3f vLocation = Vector3f.zero();
body.getLocation(vLocation);
Vector3f vDirection = new Vector3f(comp.velocity);
float fDistanceThisFrame = vDirection.length();
vDirection.normalize();
fDistanceThisFrame = fDistanceThisFrame * delta;
while (true) {
HitResult hitInfo = physics.rayTrace(vLocation, vDirection, fDistanceThisFrame + 0.5f, DEFAULT_COLLISION_GROUP);
if (hitInfo.isHit()) {
Block hitBlock = worldProvider.getBlock(hitInfo.getBlockPosition());
if (hitBlock != null) {
Vector3f vTravelledDistance = vLocation.sub(hitInfo.getHitPoint());
float fTravelledDistance = vTravelledDistance.length();
if (fTravelledDistance > fDistanceThisFrame) {
break;
}
if (hitBlock.isPenetrable()) {
if (!hitInfo.getEntity().hasComponent(BlockComponent.class)) {
entity.send(new EntityImpactEvent(hitInfo.getHitPoint(), hitInfo.getHitNormal(), comp.velocity, fDistanceThisFrame, hitInfo.getEntity()));
break;
}
// decrease the remaining distance to check if we hit a block
fDistanceThisFrame = fDistanceThisFrame - fTravelledDistance;
vLocation = hitInfo.getHitPoint();
} else {
entity.send(new BlockImpactEvent(hitInfo.getHitPoint(), hitInfo.getHitNormal(), comp.velocity, fDistanceThisFrame, hitInfo.getEntity()));
break;
}
} else {
break;
}
} else {
break;
}
}
}
}
if (networkSystem.getMode().isServer() && time.getGameTimeInMs() - TIME_BETWEEN_NETSYNCS > lastNetsync) {
sendSyncMessages();
lastNetsync = time.getGameTimeInMs();
}
List<CollisionPair> collisionPairs = physics.getCollisionPairs();
for (CollisionPair pair : collisionPairs) {
if (pair.b.exists()) {
short bCollisionGroup = getCollisionGroupFlag(pair.b);
short aCollidesWith = getCollidesWithGroupFlag(pair.a);
if ((bCollisionGroup & aCollidesWith) != 0 || (pair.b.hasComponent(BlockComponent.class) && !pair.a.hasComponent(BlockComponent.class))) {
pair.a.send(new CollideEvent(pair.b, pair.pointA, pair.pointB, pair.distance, pair.normal));
}
}
if (pair.a.exists()) {
short aCollisionGroup = getCollisionGroupFlag(pair.a);
short bCollidesWith = getCollidesWithGroupFlag(pair.b);
if ((aCollisionGroup & bCollidesWith) != 0 || (pair.a.hasComponent(BlockComponent.class) && !pair.b.hasComponent(BlockComponent.class))) {
pair.b.send(new CollideEvent(pair.a, pair.pointB, pair.pointA, pair.distance, new Vector3f(pair.normal).invert()));
}
}
}
}
use of org.terasology.physics.HitResult in project Terasology by MovingBlocks.
the class CharacterSystem method onAttackRequest.
@ReceiveEvent(components = LocationComponent.class, netFilter = RegisterMode.AUTHORITY)
public void onAttackRequest(AttackRequest event, EntityRef character, CharacterComponent characterComponent) {
// if an item is used, make sure this entity is allowed to attack with it
if (event.getItem().exists()) {
if (!character.equals(event.getItem().getOwner())) {
return;
}
}
OnItemUseEvent onItemUseEvent = new OnItemUseEvent();
character.send(onItemUseEvent);
if (!onItemUseEvent.isConsumed()) {
EntityRef gazeEntity = GazeAuthoritySystem.getGazeEntityForCharacter(character);
LocationComponent gazeLocation = gazeEntity.getComponent(LocationComponent.class);
Vector3f direction = gazeLocation.getWorldDirection();
Vector3f originPos = gazeLocation.getWorldPosition();
HitResult result = physics.rayTrace(originPos, direction, characterComponent.interactionRange, Sets.newHashSet(character), DEFAULTPHYSICSFILTER);
if (result.isHit()) {
result.getEntity().send(new AttackEvent(character, event.getItem()));
}
}
}
use of org.terasology.physics.HitResult in project Terasology by MovingBlocks.
the class ParticleUpdaterImpl method checkCollision.
// == particles =====================================================================================================
private void checkCollision(final ParticlePool pool, final int offset) {
final Vector3f vel = new Vector3f();
final Vector3f halfVelDir = new Vector3f();
final Vector3f curr = new Vector3f();
for (int i = offset; i < pool.livingParticles(); i += PHYSICS_SKIP_NR) {
int i3 = i * 3;
curr.set(pool.position[i3 + 0], pool.position[i3 + 1], pool.position[i3 + 2]);
vel.set(pool.velocity[i3 + 0], pool.velocity[i3 + 1], pool.velocity[i3 + 2]);
halfVelDir.scale(0).add(vel).normalize().scale(0.5f);
curr.sub(halfVelDir);
float dist = (vel.length() + 0.5f) * movingAvgDelta * PHYSICS_SKIP_NR * 1.5f;
vel.normalize();
HitResult hitResult = physics.rayTrace(curr, vel, dist, StandardCollisionGroup.WORLD);
if (hitResult.isHit()) {
pool.energy[i] = 0;
}
}
}
use of org.terasology.physics.HitResult in project Terasology by MovingBlocks.
the class TargetSystem method updateTarget.
public boolean updateTarget(Vector3f pos, Vector3f dir, float maxDist) {
if (targetBlockPos != null && !target.exists()) {
target = blockRegistry.getEntityAt(targetBlockPos);
}
HitResult hitInfo = physics.rayTrace(pos, dir, maxDist, filter);
EntityRef newTarget = hitInfo.getEntity();
if (hitInfo.isWorldHit()) {
if (targetBlockPos != null) {
if (targetBlockPos.equals(hitInfo.getBlockPosition())) {
return false;
}
}
targetBlockPos = hitInfo.getBlockPosition();
} else {
if (target.equals(newTarget)) {
return false;
}
targetBlockPos = null;
}
prevTarget = target;
target = newTarget;
LocationComponent location = target.getComponent(LocationComponent.class);
if (location != null && targetBlockPos != null) {
location.setLocalPosition(targetBlockPos.toVector3f());
}
return true;
}
use of org.terasology.physics.HitResult in project Terasology by MovingBlocks.
the class BulletPhysics method rayTrace.
@Override
public HitResult rayTrace(org.terasology.math.geom.Vector3f from1, org.terasology.math.geom.Vector3f direction, float distance, Set<EntityRef> excludedEntities, CollisionGroup... collisionGroups) {
if (excludedEntities == null) {
return rayTrace(from1, direction, distance, collisionGroups);
}
Vector3f to = new Vector3f(VecMath.to(direction));
Vector3f from = VecMath.to(from1);
to.scale(distance);
to.add(from);
short filter = combineGroups(collisionGroups);
// lookup all the collision item ids for these entities
Set<Integer> excludedCollisionIds = Sets.newHashSet();
for (EntityRef excludedEntity : excludedEntities) {
if (entityRigidBodies.containsKey(excludedEntity)) {
excludedCollisionIds.add(entityRigidBodies.get(excludedEntity).rb.getBroadphaseHandle().getUid());
}
if (entityColliders.containsKey(excludedEntity)) {
excludedCollisionIds.add(entityColliders.get(excludedEntity).collider.getBroadphaseHandle().getUid());
}
if (entityTriggers.containsKey(excludedEntity)) {
excludedCollisionIds.add(entityTriggers.get(excludedEntity).getBroadphaseHandle().getUid());
}
}
CollisionWorld.ClosestRayResultWithUserDataCallback closest = new ClosestRayResultWithUserDataCallbackExcludingCollisionIds(from, to, excludedCollisionIds);
closest.collisionFilterGroup = CollisionFilterGroups.ALL_FILTER;
closest.collisionFilterMask = filter;
discreteDynamicsWorld.rayTest(from, to, closest);
if (closest.hasHit()) {
if (closest.userData instanceof Vector3i) {
// We hit a world block
final EntityRef entityAt = blockEntityRegistry.getEntityAt((Vector3i) closest.userData);
return new HitResult(entityAt, VecMath.from(closest.hitPointWorld), VecMath.from(closest.hitNormalWorld), (Vector3i) closest.userData);
} else if (closest.userData instanceof EntityRef) {
// we hit an other entity
return new HitResult((EntityRef) closest.userData, VecMath.from(closest.hitPointWorld), VecMath.from(closest.hitNormalWorld));
} else {
// we hit something we don't understand, assume its nothing and log a warning
logger.warn("Unidentified object was hit in the physics engine: {}", closest.userData);
return new HitResult();
}
} else {
// nothing was hit
return new HitResult();
}
}
Aggregations