Search in sources :

Example 1 with HitResult

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()));
            }
        }
    }
}
Also used : RigidBodyComponent(org.terasology.physics.components.RigidBodyComponent) HitResult(org.terasology.physics.HitResult) BlockComponent(org.terasology.world.block.BlockComponent) CollideEvent(org.terasology.physics.events.CollideEvent) Vector3f(org.terasology.math.geom.Vector3f) BlockImpactEvent(org.terasology.physics.events.BlockImpactEvent) Block(org.terasology.world.block.Block) OnChangedBlock(org.terasology.world.OnChangedBlock) EntityImpactEvent(org.terasology.physics.events.EntityImpactEvent) EntityRef(org.terasology.entitySystem.entity.EntityRef)

Example 2 with HitResult

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()));
        }
    }
}
Also used : HitResult(org.terasology.physics.HitResult) OnItemUseEvent(org.terasology.logic.characters.events.OnItemUseEvent) Vector3f(org.terasology.math.geom.Vector3f) EntityRef(org.terasology.entitySystem.entity.EntityRef) LocationComponent(org.terasology.logic.location.LocationComponent) AttackEvent(org.terasology.logic.characters.events.AttackEvent) ReceiveEvent(org.terasology.entitySystem.event.ReceiveEvent)

Example 3 with HitResult

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;
        }
    }
}
Also used : HitResult(org.terasology.physics.HitResult) Vector3f(org.terasology.math.geom.Vector3f)

Example 4 with HitResult

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;
}
Also used : HitResult(org.terasology.physics.HitResult) EntityRef(org.terasology.entitySystem.entity.EntityRef) LocationComponent(org.terasology.logic.location.LocationComponent)

Example 5 with HitResult

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();
    }
}
Also used : HitResult(org.terasology.physics.HitResult) Vector3f(javax.vecmath.Vector3f) CollisionWorld(com.bulletphysics.collision.dispatch.CollisionWorld) Vector3i(org.terasology.math.geom.Vector3i) EntityRef(org.terasology.entitySystem.entity.EntityRef)

Aggregations

HitResult (org.terasology.physics.HitResult)10 EntityRef (org.terasology.entitySystem.entity.EntityRef)9 Vector3f (org.terasology.math.geom.Vector3f)8 LocationComponent (org.terasology.logic.location.LocationComponent)4 ReceiveEvent (org.terasology.entitySystem.event.ReceiveEvent)3 Vector3i (org.terasology.math.geom.Vector3i)3 Block (org.terasology.world.block.Block)2 BlockComponent (org.terasology.world.block.BlockComponent)2 CollisionWorld (com.bulletphysics.collision.dispatch.CollisionWorld)1 Vector3f (javax.vecmath.Vector3f)1 EntityBuilder (org.terasology.entitySystem.entity.EntityBuilder)1 CharacterComponent (org.terasology.logic.characters.CharacterComponent)1 CharacterHeldItemComponent (org.terasology.logic.characters.CharacterHeldItemComponent)1 ActivationPredicted (org.terasology.logic.characters.events.ActivationPredicted)1 ActivationRequest (org.terasology.logic.characters.events.ActivationRequest)1 AttackEvent (org.terasology.logic.characters.events.AttackEvent)1 OnItemUseEvent (org.terasology.logic.characters.events.OnItemUseEvent)1 DoDamageEvent (org.terasology.logic.health.DoDamageEvent)1 DropItemRequest (org.terasology.logic.inventory.events.DropItemRequest)1 PlayerCharacterComponent (org.terasology.logic.players.PlayerCharacterComponent)1