private void playMovementSound() { if (_godMode) return; if ((MathHelper.fastAbs(_velocity.x) > 0.01 || MathHelper.fastAbs(_velocity.z) > 0.01) && _touchingGround) { if (_currentFootstepSound == null) { Vector3d playerDirection = directionOfReferencePoint(); _currentFootstepSound = _footstepSounds[ MathHelper.fastAbs(_parent.getWorldProvider().getRandom().randomInt()) % 5]; _currentFootstepSound.playAsSoundEffect( 0.7f + (float) MathHelper.fastAbs(_parent.getWorldProvider().getRandom().randomDouble()) * 0.3f, 0.2f + (float) MathHelper.fastAbs(_parent.getWorldProvider().getRandom().randomDouble()) * 0.2f, false, (float) playerDirection.x, (float) playerDirection.y, (float) playerDirection.z); } else { long timeDiff = Terasology.getInstance().getTime() - _lastFootStepSoundPlayed; if (!_currentFootstepSound.isPlaying() && timeDiff > 400 / (_activeWalkingSpeed / _walkingSpeed)) { _lastFootStepSoundPlayed = Terasology.getInstance().getTime(); _currentFootstepSound = null; } } } }
@Override public boolean step() { EntityManager entityManager = context.get(EntityManager.class); WorldRenderer worldRenderer = context.get(WorldRenderer.class); Iterator<EntityRef> worldEntityIterator = entityManager.getEntitiesWith(WorldComponent.class).iterator(); // TODO: Move the world renderer bits elsewhere if (worldEntityIterator.hasNext()) { EntityRef worldEntity = worldEntityIterator.next(); worldRenderer.getChunkProvider().setWorldEntity(worldEntity); // get the world generator config from the world entity // replace the world generator values from the components in the world entity WorldGenerator worldGenerator = context.get(WorldGenerator.class); WorldConfigurator worldConfigurator = worldGenerator.getConfigurator(); Map<String, Component> params = worldConfigurator.getProperties(); for (Map.Entry<String, Component> entry : params.entrySet()) { Class<? extends Component> clazz = entry.getValue().getClass(); Component comp = worldEntity.getComponent(clazz); if (comp != null) { worldConfigurator.setProperty(entry.getKey(), comp); } } } else { EntityRef worldEntity = entityManager.create(); worldEntity.addComponent(new WorldComponent()); worldRenderer.getChunkProvider().setWorldEntity(worldEntity); // transfer all world generation parameters from Config to WorldEntity WorldGenerator worldGenerator = context.get(WorldGenerator.class); SimpleUri generatorUri = worldGenerator.getUri(); Config config = context.get(Config.class); // get the map of properties from the world generator. // Replace its values with values from the config set by the UI. // Also set all the components to the world entity. WorldConfigurator worldConfigurator = worldGenerator.getConfigurator(); Map<String, Component> params = worldConfigurator.getProperties(); for (Map.Entry<String, Component> entry : params.entrySet()) { Class<? extends Component> clazz = entry.getValue().getClass(); Component comp = config.getModuleConfig(generatorUri, entry.getKey(), clazz); if (comp != null) { worldEntity.addComponent(comp); worldConfigurator.setProperty(entry.getKey(), comp); } else { worldEntity.addComponent(entry.getValue()); } } } return true; }
/** Updates the status if the entity is currently swimming (in water). */ private void updateSwimStatus() { ArrayList<BlockPosition> blockPositions = gatherAdjacentBlockPositions(getPosition()); boolean swimming = false, headUnderWater = false; for (int i = 0; i < blockPositions.size(); i++) { BlockPosition p = blockPositions.get(i); byte blockType = _parent.getWorldProvider().getBlockAtPosition(new Vector3d(p.x, p.y, p.z)); AABB blockAABB = Block.AABBForBlockAt(p.x, p.y, p.z); if (BlockManager.getInstance().getBlock(blockType).isLiquid() && getAABB().overlaps(blockAABB)) { swimming = true; } Vector3d eyePos = calcEyePosition(); eyePos.y += 0.25; if (BlockManager.getInstance().getBlock(blockType).isLiquid() && blockAABB.contains(eyePos)) { headUnderWater = true; } } _headUnderWater = headUnderWater; _isSwimming = swimming; }
@Override public boolean step() { if (worldRenderer.pregenerateChunks()) { return true; } EngineTime time = (EngineTime) context.get(Time.class); long totalTime = time.getRawTimeInMs() - startTime; return totalTime > 5000; }
public void render() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); if (_worldRenderer != null) { _worldRenderer.render(); } /* UI */ PerformanceMonitor.startActivity("Render and Update UI"); renderUserInterface(); PerformanceMonitor.endActivity(); }
public void render() { FloatBuffer mBuffer = BufferUtils.createFloatBuffer(16); float[] mFloat = new float[16]; GL11.glPushMatrix(); Vector3d cameraPosition = _parent.getActiveCamera().getPosition(); GL11.glTranslated(-cameraPosition.x, -cameraPosition.y, -cameraPosition.z); List<CollisionObject> collisionObjects = _discreteDynamicsWorld.getCollisionObjectArray(); for (CollisionObject co : collisionObjects) { if (co.getClass().equals(BlockRigidBody.class)) { BlockRigidBody br = (BlockRigidBody) co; Block block = BlockManager.getInstance().getBlock(br.getType()); Transform t = new Transform(); br.getMotionState().getWorldTransform(t); t.getOpenGLMatrix(mFloat); mBuffer.put(mFloat); mBuffer.flip(); GL11.glPushMatrix(); GL11.glMultMatrix(mBuffer); if (br.getCollisionShape() == _blockShapeHalf) GL11.glScalef(0.5f, 0.5f, 0.5f); else if (br.getCollisionShape() == _blockShapeQuarter) GL11.glScalef(0.25f, 0.25f, 0.25f); block.renderWithLightValue(_parent.getRenderingLightValueAt(new Vector3d(t.origin))); GL11.glPopMatrix(); } } GL11.glPopMatrix(); }
public void update(float delta) { for (EntityRef entity : entityManager.iteratorEntities(MiniaturizerComponent.class)) { MiniaturizerComponent min = entity.getComponent(MiniaturizerComponent.class); if (min.chunkMesh == null && min.miniatureChunk != null) { min.chunkMesh = worldRenderer.getChunkTesselator().generateMinaturizedMesh(min.miniatureChunk); min.chunkMesh.generateVBOs(); min.chunkMesh._vertexElements = null; } // min.orientation += delta * 15f; } }
/** * Checks for blocks around the entity. * * @param origin The original position of the entity * @return True if the entity is colliding horizontally */ private boolean horizontalHitTest(Vector3d origin) { boolean result = false; ArrayList<BlockPosition> blockPositions = gatherAdjacentBlockPositions(origin); // Check each block position for collision for (int i = 0; i < blockPositions.size(); i++) { BlockPosition p = blockPositions.get(i); byte blockType = _parent.getWorldProvider().getBlockAtPosition(new Vector3d(p.x, p.y, p.z)); AABB blockAABB = Block.AABBForBlockAt(p.x, p.y, p.z); if (!BlockManager.getInstance().getBlock(blockType).isPenetrable()) { if (getAABB().overlaps(blockAABB)) { result = true; // Calculate the direction from the origin to the current position Vector3d direction = new Vector3d(getPosition().x, 0f, getPosition().z); direction.x -= origin.x; direction.z -= origin.z; // Calculate the point of intersection on the block's AABB Vector3d blockPoi = blockAABB.closestPointOnAABBToPoint(origin); Vector3d entityPoi = generateAABBForPosition(origin).closestPointOnAABBToPoint(blockPoi); Vector3d planeNormal = blockAABB.normalForPlaneClosestToOrigin(blockPoi, origin, true, false, true); // Find a vector parallel to the surface normal Vector3d slideVector = new Vector3d(planeNormal.z, 0, -planeNormal.x); Vector3d pushBack = new Vector3d(); pushBack.sub(blockPoi, entityPoi); // Calculate the intensity of the diversion alongside the block double length = slideVector.dot(direction); Vector3d newPosition = new Vector3d(); newPosition.z = origin.z + pushBack.z * 0.2 + length * slideVector.z; newPosition.x = origin.x + pushBack.x * 0.2 + length * slideVector.x; newPosition.y = origin.y; // Update the position getPosition().set(newPosition); } } } return result; }
public String toString() { Camera camera = worldRenderer.getActiveCamera(); if (targetBlockPos != null) { return String.format( "From: %f %f %f, Dir: %f %f %f, Hit %d %d %d %f %f %f", camera.getPosition().x, camera.getPosition().y, camera.getPosition().z, camera.getViewingDirection().x, camera.getViewingDirection().y, camera.getViewingDirection().z, targetBlockPos.x, targetBlockPos.y, targetBlockPos.z, hitPosition.x, hitPosition.y, hitPosition.z); } return ""; }
public void update(float delta) { // Repair lost target // TODO: Improvements to temporary chunk handling will remove the need for this boolean lostTarget = false; updateTarget(); if (!target.exists()) { targetBlockPos = null; lostTarget = true; } // TODO: This will change when camera are handled better (via a component) Camera camera = worldRenderer.getActiveCamera(); HitResult hitInfo = physics.rayTrace( new Vector3f(camera.getPosition()), new Vector3f(camera.getViewingDirection()), targetDistance, filter); updateFocalDistance(hitInfo, delta); Vector3i newBlockPos = null; EntityRef newTarget = EntityRef.NULL; if (hitInfo.isHit()) { newTarget = hitInfo.getEntity(); hitPosition = hitInfo.getHitPoint(); hitNormal = hitInfo.getHitNormal(); if (hitInfo.isWorldHit()) { newBlockPos = new Vector3i(hitInfo.getBlockPosition()); } } if (!Objects.equal(target, newTarget) || lostTarget) { EntityRef oldTarget = target; oldTarget.send(new CameraOutEvent()); newTarget.send(new CameraOverEvent()); localPlayer.getCharacterEntity().send(new CameraTargetChangedEvent(oldTarget, newTarget)); } target = newTarget; targetBlockPos = newBlockPos; }
/** * Checks for blocks below and above the entity. * * @param origin The origin position of the entity * @return True if a vertical collision was detected */ private boolean verticalHitTest(Vector3d origin) { ArrayList<BlockPosition> blockPositions = gatherAdjacentBlockPositions(origin); for (int i = 0; i < blockPositions.size(); i++) { BlockPosition p = blockPositions.get(i); byte blockType1 = _parent.getWorldProvider().getBlockAtPosition(new Vector3d(p.x, p.y, p.z)); AABB entityAABB = getAABB(); if (BlockManager.getInstance().getBlock(blockType1).isPenetrable() || !entityAABB.overlaps(Block.AABBForBlockAt(p.x, p.y, p.z))) continue; double direction = origin.y - getPosition().y; if (direction >= 0) getPosition().y = p.y + 0.50001f + entityAABB.getDimensions().y; else getPosition().y = p.y - 0.50001f - entityAABB.getDimensions().y; return true; } return false; }
public void update(float delta) { /* GUI */ updateUserInterface(); for (UpdateSubscriberSystem updater : _componentSystemManager.iterateUpdateSubscribers()) { PerformanceMonitor.startActivity(updater.getClass().getSimpleName()); updater.update(delta); } if (_worldRenderer != null && shouldUpdateWorld()) _worldRenderer.update(delta); if (!screenHasFocus()) _localPlayerSys.updateInput(); if (screenHasFocus() || !shouldUpdateWorld()) { if (Mouse.isGrabbed()) { Mouse.setGrabbed(false); Mouse.setCursorPosition(Display.getWidth() / 2, Display.getHeight() / 2); } } else { if (!Mouse.isGrabbed()) Mouse.setGrabbed(true); } // TODO: This seems a little off - plus is more of a UI than single player game state concern. // Move somewhere // more appropriate? boolean dead = true; for (EntityRef entity : _entityManager.iteratorEntities(LocalPlayerComponent.class)) { dead = entity.getComponent(LocalPlayerComponent.class).isDead; } if (dead) { _statusScreen.setVisible(true); _statusScreen.updateStatus("Sorry! Seems like you have died. :-("); } else { _statusScreen.setVisible(false); } }
private void checkPosition() { if (!_godMode && getPosition().y < 0) { getPosition().y = _parent.maxHeightAt((int) getPosition().x, (int) getPosition().y); } }
public Vector3d directionOfReferencePoint() { Vector3d result = new Vector3d(); result.sub(_parent.getWorldProvider().getRenderingReferencePoint(), getPosition()); return result; }
/** Updates the position of the entity. */ protected void updatePosition() { // Save the previous position before changing any of the values Vector3d oldPosition = new Vector3d(getPosition()); double friction = (Double) ConfigurationManager.getInstance().getConfig().get("Player.friction"); /* * Slowdown the speed of the entity each time this method is called. */ if (MathHelper.fastAbs(_velocity.y) > 0f) { _velocity.y += -1f * _velocity.y * friction; } if (MathHelper.fastAbs(_velocity.x) > 0f) { _velocity.x += -1f * _velocity.x * friction; } if (MathHelper.fastAbs(_velocity.z) > 0f) { _velocity.z += -1f * _velocity.z * friction; } /* * Apply friction. */ if (MathHelper.fastAbs(_velocity.x) > _activeWalkingSpeed || MathHelper.fastAbs(_velocity.z) > _activeWalkingSpeed || MathHelper.fastAbs(_velocity.y) > _activeWalkingSpeed) { double max = Math.max( Math.max(MathHelper.fastAbs(_velocity.x), MathHelper.fastAbs(_velocity.z)), MathHelper.fastAbs(_velocity.y)); double div = max / _activeWalkingSpeed; _velocity.x /= div; _velocity.z /= div; _velocity.y /= div; } /* * Increase the speed of the entity by adding the movement * vector to the acceleration vector. */ _velocity.x += _movementDirection.x; _velocity.y += _movementDirection.y; _velocity.z += _movementDirection.z; double maxGravity = (Double) ConfigurationManager.getInstance().getConfig().get("Player.maxGravity"); double maxGravitySwimming = (Double) ConfigurationManager.getInstance().getConfig().get("Player.maxGravitySwimming"); double gravitySwimming = (Double) ConfigurationManager.getInstance().getConfig().get("Player.gravitySwimming"); double gravity = (Double) ConfigurationManager.getInstance().getConfig().get("Player.gravity"); // Normal gravity if (_gravity > -maxGravity && !_godMode && !_isSwimming) { _gravity -= gravity; } if (_gravity < -maxGravity && !_godMode && !_isSwimming) { _gravity = -maxGravity; } // Gravity under water if (_gravity > -maxGravitySwimming && !_godMode && _isSwimming) { _gravity -= gravitySwimming; } if (_gravity < -maxGravitySwimming && !_godMode && _isSwimming) { _gravity = -maxGravitySwimming; } getPosition().y += _velocity.y; getPosition().y += _gravity; if (!_godMode) { if (verticalHitTest(oldPosition)) { handleVerticalCollision(); double oldGravity = _gravity; _gravity = 0; if (oldGravity <= 0) { // Jumping is only possible, if the entity is standing on ground if (_jump) { _jump = false; _gravity = _jumpIntensity; } // Entity reaches the ground if (!_touchingGround) { Vector3d playerDirection = directionOfReferencePoint(); _footstepSounds[ MathHelper.fastAbs(_parent.getWorldProvider().getRandom().randomInt()) % 5] .playAsSoundEffect( 0.7f + (float) MathHelper.fastAbs( _parent.getWorldProvider().getRandom().randomDouble()) * 0.3f, 0.2f + (float) MathHelper.fastAbs( _parent.getWorldProvider().getRandom().randomDouble()) * 0.3f, false, (float) playerDirection.x, (float) playerDirection.y, (float) playerDirection.z); _touchingGround = true; } } else { _touchingGround = false; } } else { _touchingGround = false; } } else { _gravity = 0f; } oldPosition.set(getPosition()); /* * Update the position of the entity * according to the acceleration vector. */ getPosition().x += _velocity.x; getPosition().z += _velocity.z; _stepCounter += Math.max(MathHelper.fastAbs(_velocity.x), MathHelper.fastAbs(_velocity.z)); /* * Check for horizontal collisions __after__ checking for vertical * collisions. */ if (!_godMode) { if (horizontalHitTest(oldPosition)) { handleHorizontalCollision(); } } }
public void dispose() { _worldRenderer.dispose(); _worldRenderer = null; }
public IWorldProvider getActiveWorldProvider() { return _worldRenderer.getWorldProvider(); }
/** Init. a new random world. */ public void initWorld(String title, String seed) { final FastRandom random = new FastRandom(); // Get rid of the old world if (_worldRenderer != null) { _worldRenderer.dispose(); _worldRenderer = null; } if (seed == null) { seed = random.randomCharacterString(16); } else if (seed.isEmpty()) { seed = random.randomCharacterString(16); } Terasology.getInstance() .getLogger() .log(Level.INFO, "Creating new World with seed \"{0}\"", seed); // Init. a new world _worldRenderer = new WorldRenderer(title, seed, _entityManager, _localPlayerSys); File entityDataFile = new File(Terasology.getInstance().getWorldSavePath(title), ENTITY_DATA_FILE); _entityManager.clear(); if (entityDataFile.exists()) { try { _entityManager.load(entityDataFile, EntityManager.SaveFormat.Binary); } catch (IOException e) { _logger.log(Level.SEVERE, "Failed to load entity data", e); } } LocalPlayer localPlayer = null; Iterator<EntityRef> iterator = _entityManager.iteratorEntities(LocalPlayerComponent.class).iterator(); if (iterator.hasNext()) { localPlayer = new LocalPlayer(iterator.next()); } else { PlayerFactory playerFactory = new PlayerFactory(_entityManager); localPlayer = new LocalPlayer( playerFactory.newInstance( new Vector3f(_worldRenderer.getWorldProvider().nextSpawningPoint()))); } _worldRenderer.setPlayer(localPlayer); // Create the first Portal if it doesn't exist yet _worldRenderer.initPortal(); fastForwardWorld(); CoreRegistry.put(WorldRenderer.class, _worldRenderer); CoreRegistry.put(IWorldProvider.class, _worldRenderer.getWorldProvider()); CoreRegistry.put(LocalPlayer.class, _worldRenderer.getPlayer()); CoreRegistry.put(Camera.class, _worldRenderer.getActiveCamera()); CoreRegistry.put(BulletPhysicsRenderer.class, _worldRenderer.getBulletRenderer()); for (ComponentSystem system : _componentSystemManager.iterateAll()) { system.initialise(); } }