public SpoutEntity( SpoutEngine engine, Transform transform, Controller controller, int viewDistance, UUID uid, boolean load) { id.set(NOTSPAWNEDID); this.transform.set(transform); if (uid != null) { this.uid = uid; } else { this.uid = UUID.randomUUID(); } chunkLive = new AtomicReference<Chunk>(); entityManagerLive = new AtomicReference<EntityManager>(); controllerLive = new AtomicReference<Controller>(); if (transform != null && load) { chunkLive.set(transform.getPosition().getWorld().getChunkFromBlock(transform.getPosition())); entityManagerLive.set(((SpoutRegion) chunkLive.get().getRegion()).getEntityManager()); } viewDistanceLive.set(viewDistance); controllerLive.set(controller); if (controller != null) { controller.attachToEntity(this); if (controller instanceof PlayerController) { setObserver(true); } } }
@Override public void updateView() { Transform transform = ((PredictableTransformComponent) getOwner().getTransform()).getRenderTransform(); if (transform != null) { Matrix pos = MathHelper.translate(transform.getPosition().multiply(-1)); Matrix rot = MathHelper.rotate(transform.getRotation()); view = pos.multiply(rot); frustum.update(projection, view, transform.getPosition()); } }
private void updateObserver() { // Player view distance is handled in the network synchronizer if (controllerLive.get() instanceof PlayerController) { return; } int viewDistance = (getViewDistance() + 15) / Chunk.CHUNK_SIZE; // round up World w = transform.getPosition().getWorld(); int cx = chunkLive.get().getX(); int cy = chunkLive.get().getY(); int cz = chunkLive.get().getZ(); HashSet<SpoutChunk> observing = new HashSet<SpoutChunk>(viewDistance * viewDistance * viewDistance); for (int dx = -viewDistance; dx < viewDistance; dx++) { for (int dy = -viewDistance; dy < viewDistance; dy++) { for (int dz = -viewDistance; dz < viewDistance; dz++) { Chunk chunk = w.getChunk(cx + dx, cy + dy, cz + dz, true); chunk.refreshObserver(this); observing.add((SpoutChunk) chunk); } } } observingChunks.removeAll(observing); for (SpoutChunk chunk : observingChunks) { if (chunk.isLoaded()) { chunk.removeObserver(this); } } observingChunks.clear(); observingChunks.addAll(observing); }
@Override public void onTick(float dt) { Controller cont = controllerLive.get(); // Pulse all player messages here, so they can interact with the entities position safely if (cont instanceof PlayerController) { Player player = ((PlayerController) cont).getPlayer(); if (player != null && player.getSession() != null) { ((SpoutSession) player.getSession()).pulse(); } } // Tick the controller if (cont != null) { // Sanity check if (cont.getParent() != this) { if (Spout.debugMode()) { throw new IllegalStateException("Controller parent does not match entity"); } else { cont.attachToEntity(this); } } // If this is the first tick, we need to attach the controller // Controller is attached here instead of inside of the constructor // because the constructor can not access getChunk if the entity is being deserialized if (!attached) { cont.onAttached(); attached = true; } cont.onTick(dt); } // Copy values last (position may change during controller or session pulses) if (!isDead() && this.transform.getPosition() != null && this.transform.getPosition().getWorld() != null) { // Note: if the chunk is null, this effectively kills the entity (since dead: {chunkLive.get() // == null}) chunkLive.set( transform.getPosition().getWorld().getChunkFromBlock(transform.getPosition(), false)); entityManagerLive.set(((SpoutRegion) getRegion()).getEntityManager()); lastTransform = transform.copy(); } }
public void render(float dt) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (Mouse.isButtonDown(0)) { if (!Mouse.isGrabbed()) Mouse.setGrabbed(true); } else Mouse.setGrabbed(false); // worldRenderer.render(); try { // System.out.println("view "+activeCamera.getView().toString()); Transform loc = new Transform(new Point(null, 0f, 0f, 0f), Quaternion.IDENTITY, Vector3.ONE); mat.getShader().setUniform("View", activeCamera.getView()); mat.getShader().setUniform("Projection", activeCamera.getProjection()); mat.getShader().setUniform("Model", loc.toMatrix()); renderer.draw(mat); gui.begin(); gui.draw(mat, .25f, .25f, .25f, .25f); gui.render(); } catch (Exception e) { } }
// TODO set up number of stages ? public SpoutWorld( String name, SpoutEngine engine, long seed, long age, WorldGenerator generator, UUID uid, StringMap itemMap, StringMap lightingMap) { this.engine = engine; if (!StringSanitizer.isAlphaNumericUnderscore(name)) { name = Long.toHexString(System.currentTimeMillis()); getEngine() .getLogger() .severe("World name " + name + " is not valid, using " + name + " instead"); } this.name = name; this.uid = uid; this.itemMap = itemMap; this.lightingMap = lightingMap; this.seed = seed; this.generator = generator; regions = new RegionSource(this, snapshotManager); worldDirectory = new File(engine.getWorldFolder(), name); worldDirectory.mkdirs(); regionFileManager = new RegionFileManager(worldDirectory); heightMapBAAs = new TSyncIntPairObjectHashMap<BAAWrapper>(); this.hashcode = new HashCodeBuilder(27, 971).append(uid).toHashCode(); for (int i = 0; i < columnLockMap.length; i++) { columnLockMap[i] = new ReentrantLock(); } parallelTaskManager = new SpoutParallelTaskManager(engine.getScheduler(), this); lightingManagers = new UnprotectedCopyOnUpdateArray<LightingManager<?>>(LightingManager.class, true); this.age = new SnapshotableLong(snapshotManager, age); taskManager = new SpoutTaskManager(getEngine().getScheduler(), null, this, age); spawnLocation.set(new Transform(new Point(this, 1, 100, 1), Quaternion.IDENTITY, Vector3.ONE)); selfReference = new WeakReference<SpoutWorld>(this); getEngine().getScheduler().addAsyncManager(this); }
@Override public BlockIterator getAlignedBlocks() { Player player = (Player) getOwner(); Transform ptr = player.get(PlayerHead.class).getHeadTransform(); Transform tr = new Transform(); tr.setRotation( QuaternionMath.rotationTo(Vector3.FORWARD, ptr.getRotation().getDirection().multiply(-1))); tr.setPosition(ptr.getPosition()); return new BlockIterator(player.getWorld(), tr, getRange()); }
@DelayedWrite public boolean connect(SpoutSession<?> session, Transform newTransform) { if (!onlineLive.compareAndSet(false, true)) { // player was already online return false; } // Disallow null transforms or transforms with null worlds if (newTransform == null || newTransform.getPosition().getWorld() == null) { return false; } getTransform().setTransform(newTransform); setupInitialChunk(newTransform); sessionLive.set(session); copySnapshot(); return true; }
@Override public void onTick(float dt) { final Client client = (Client) Spout.getEngine(); final Transform playerTransform = client.getPlayer().getPhysics().getTransform(); final PlayerInputState state = client.getPlayer().input(); final float speed = 50f; Vector3f motion = Vector3f.ZERO; if (state.getForward()) { motion = motion.add(playerTransform.forwardVector().mul(speed * -dt)); } if (state.getBackward()) { motion = motion.add(playerTransform.forwardVector().mul(speed * dt)); } if (state.getLeft()) { motion = motion.add(playerTransform.rightVector().mul(speed * -dt)); // TODO getLeftVector } if (state.getRight()) { motion = motion.add(playerTransform.rightVector().mul(speed * dt)); } if (state.getJump()) { motion = motion.add(playerTransform.upVector().mul(speed * dt)); } if (state.getCrouch()) { motion = motion.add(playerTransform.upVector().mul(speed * -dt)); } client .getPlayer() .getPhysics() .setRotation( Quaternionf.fromAxesAnglesDeg( state.pitch(), state.yaw(), playerTransform.getRotation().getAxesAngleDeg().getZ())); if (!motion.equals(Vector3f.ZERO)) { client.getPlayer().getPhysics().translate(motion); } }
@Override public List<Message> getUpdateMessages( Entity entity, Transform liveTransform, RepositionManager rm, boolean force) { // Movement final Transform prevTransform = rm.convert(entity.getScene().getTransform()); final Transform newTransform = rm.convert(liveTransform); final boolean looked = entity.getScene().isRotationDirty(); final int lastX = protocolifyPosition(prevTransform.getPosition().getX()); final int lastY = protocolifyPosition(prevTransform.getPosition().getY()); final int lastZ = protocolifyPosition(prevTransform.getPosition().getZ()); final int lastYaw = protocolifyYaw(prevTransform.getRotation().getYaw()); final int lastPitch = protocolifyPitch(prevTransform.getRotation().getPitch()); final int newX = protocolifyPosition(newTransform.getPosition().getX()); final int newY = protocolifyPosition(newTransform.getPosition().getY()); final int newZ = protocolifyPosition(newTransform.getPosition().getZ()); final int newYaw = protocolifyYaw(newTransform.getRotation().getYaw()); final int newPitch = protocolifyPitch(newTransform.getRotation().getPitch()); final int deltaX = newX - lastX; final int deltaY = newY - lastY; final int deltaZ = newZ - lastZ; final int deltaYaw = newYaw - lastYaw; final int deltaPitch = newPitch - lastPitch; final List<Message> messages = new ArrayList<Message>(); /* * Two scenarios: * - The entity moves more than 4 blocks and maybe changes rotation. * - The entity moves less than 4 blocks and maybe changes rotation. */ if (force || deltaX > 128 || deltaX < -128 || deltaY > 128 || deltaY < -128 || deltaZ > 128 || deltaZ < -128) { messages.add(new EntityTeleportMessage(entity.getId(), newX, newY, newZ, newYaw, newPitch)); if (force || looked) { messages.add(new EntityYawMessage(entity.getId(), newYaw, newPitch)); } } else if (deltaX != 0 || deltaY != 0 || deltaZ != 0 || deltaYaw != 0 || deltaPitch != 0) { if (looked) { messages.add( new EntityRelativePositionYawMessage( entity.getId(), deltaX, deltaY, deltaZ, newYaw, newPitch)); } else if (!prevTransform.getPosition().equals(newTransform.getPosition())) { messages.add(new EntityRelativePositionMessage(entity.getId(), deltaX, deltaY, deltaZ)); } } // Head movement HeadComponent head = entity.get(HeadComponent.class); if (head != null && head.isDirty()) { final int headYawProt = ChannelBufferUtils.protocolifyYaw(head.getRotation().getYaw()); messages.add(new EntityHeadYawMessage(entity.getId(), headYawProt)); } // Physics // TODO: Actually not used? /*if (physics != null && physics.isLinearVelocityDirty()) { messages.add(new EntityVelocityMessage(entity.getId(), new Vector3(0, 0, 0))); }*/ // Extra metadata List<Parameter<?>> params = getUpdateParameters(entity); if (lastMeta == null || !lastMeta.equals(params)) { messages.add(new EntityMetadataMessage(entity.getId(), params)); lastMeta = params; } return messages; }
@Override public Transform getTransform() { return transform.copy(); }
public void doInput() { // inputManager.pollInput(); // One Mouse.getDX() to rule them all // TODO move this a plugin if (activePlayer == null) { return; } if (Mouse.isGrabbed()) { Transform ts = activePlayer.getTransform().getTransform(); float pitch = ts.getRotation().getPitch(); float yaw = ts.getRotation().getYaw(); float mouseDX = -Mouse.getDX() * 0.16f; float mouseDY = Mouse.getDY() * 0.16f; if (yaw + mouseDX >= 360) yaw += mouseDX - 360; else if (yaw + mouseDX < 0) yaw += mouseDX + 360; else yaw += mouseDX; if (pitch + mouseDY >= -80 && pitch + mouseDY <= 80) pitch += mouseDY; else if (pitch + mouseDY < -80) pitch = -80; else if (pitch + mouseDY > 80) pitch = 80; // System.out.println("yaw: "+yaw+" pitch: "+pitch); ts.setRotation(MathHelper.rotation(pitch, yaw, ts.getRotation().getRoll())); activePlayer.getTransform().setTransform(ts); // System.out.println(activePlayer.getTransform().getTransform().toMatrix().toString()); } boolean keyUp = Keyboard.isKeyDown(Keyboard.KEY_UP) || Keyboard.isKeyDown(Keyboard.KEY_Z); boolean keyDown = Keyboard.isKeyDown(Keyboard.KEY_DOWN) || Keyboard.isKeyDown(Keyboard.KEY_S); boolean keyLeft = Keyboard.isKeyDown(Keyboard.KEY_LEFT) || Keyboard.isKeyDown(Keyboard.KEY_Q); boolean keyRight = Keyboard.isKeyDown(Keyboard.KEY_RIGHT) || Keyboard.isKeyDown(Keyboard.KEY_D); boolean flyUp = Keyboard.isKeyDown(Keyboard.KEY_SPACE); boolean flyDown = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT); Point point = new Point(Point.ONE, activePlayer.getWorld()); if (keyUp) { point = point.multiply(activePlayer.getTransform().getTransform().forwardVector()); // activePlayer.getTransform().setPosition(activePlayer.getTransform().getPosition().subtract(activePlayer.getTransform().getTransform().forwardVector())); } if (keyDown) { point = point.multiply(activePlayer.getTransform().getTransform().forwardVector().multiply(-1)); // activePlayer.getTransform().setPosition(activePlayer.getTransform().getPosition().add(activePlayer.getTransform().getTransform().forwardVector())); } if (keyLeft) { point = point.multiply(activePlayer.getTransform().getTransform().rightVector()); // activePlayer.getTransform().setPosition(activePlayer.getTransform().getPosition().subtract(activePlayer.getTransform().getTransform().rightVector())); } if (keyRight) { point = point.multiply(activePlayer.getTransform().getTransform().rightVector().multiply(-1)); // activePlayer.getTransform().setPosition(activePlayer.getTransform().getPosition().add(activePlayer.getTransform().getTransform().rightVector())); } if (flyUp) { point = point.multiply(activePlayer.getTransform().getTransform().upVector()); // activePlayer.getTransform().setPosition(activePlayer.getTransform().getPosition().add(activePlayer.getTransform().getTransform().upVector())); } if (flyDown) { point = point.multiply(activePlayer.getTransform().getTransform().upVector().multiply(-1)); // activePlayer.getTransform().setPosition(activePlayer.getTransform().getPosition().subtract(activePlayer.getTransform().getTransform().upVector())); } if (keyUp || keyDown || keyLeft || keyRight || flyUp || flyDown) { // point = new Point(point.normalize(),activePlayer.getWorld()); System.out.println("Translation : " + point.getX() + "/" + point.getY() + "/" + point.getZ()); System.out.println( "Position : " + activePlayer.getTransform().getPosition().getX() + "/" + activePlayer.getTransform().getPosition().getY() + "/" + activePlayer.getTransform().getPosition().getZ()); activePlayer.getTransform().setPosition(activePlayer.getTransform().getPosition().add(point)); } /*for (Flags f : activePlayer.input().getFlagSet()) { switch(f) { case FORWARD: activePlayer.getTransform().setPosition(activePlayer.getTransform().getPosition().add(activePlayer.getTransform().getTransform().forwardVector())); break; case BACKWARD: activePlayer.getTransform().setPosition(activePlayer.getTransform().getPosition().subtract(activePlayer.getTransform().getTransform().forwardVector())); break; case LEFT: activePlayer.getTransform().setPosition(activePlayer.getTransform().getPosition().add(activePlayer.getTransform().getTransform().rightVector())); break; case RIGHT: activePlayer.getTransform().setPosition(activePlayer.getTransform().getPosition().subtract(activePlayer.getTransform().getTransform().rightVector())); break; case CROUCH: case FIRE_1: case FIRE_2: case INTERACT: case JUMP: case SELECT_DOWN: case SELECT_UP: } }*/ }
@Override public void setSpawnPoint(Transform transform) { spawnLocation.set(transform); }
@Override public Transform getSpawnPoint() { return spawnLocation.copy(); }
@Override public void setPosition(Point position) { if (activeThreadIsValid("set position")) { transform.setPosition(position); } }
@Override public Point getPosition() { return transform.getPosition(); }
@Override public World getWorld() { return transform.getPosition().getWorld(); }
@Override public Quaternion getRotation() { return transform.getRotation(); }
@Override public float getRoll() { return transform.getRotation().getRoll(); }
@Override public void setScale(Vector3 scale) { if (activeThreadIsValid("set scale")) { transform.setScale(scale); } }
@Override public void setRotation(Quaternion rotation) { if (activeThreadIsValid("set rotation")) { transform.setRotation(rotation); } }
@Override public Transform getLastTransform() { return lastTransform.copy(); }
@Override public Transform convert(Transform t) { return new Transform(convert(t.getPosition()), t.getRotation(), t.getScale()); }
@Override public Vector3 getScale() { return transform.getScale(); }