protected void applyDelta(Vector3f deltaTranslation, Quaternion deltaRotation) { LOGGER.warning("Applying delta: " + deltaTranslation + " " + deltaRotation); boolean startedDrag = false; if (!dragging) { // no drag in progress. Start one now and end it after the drag // operation startDrag(); startedDrag = true; } for (Cell cell : selected.getSelectedCells()) { CellTransform transform = cell.getLocalTransform(); Vector3f translate = transform.getTranslation(null); Quaternion rotation = transform.getRotation(null); // if the cell has a parent, make sure to take the parent's // rotation and scale into account when applying the delta Vector3f localDeltaTranslation = deltaTranslation.clone(); Cell parent = cell.getParent(); if (parent != null) { CellTransform parentWorld = parent.getWorldTransform(); Quaternion parentRotation = parentWorld.getRotation(null); float parentScale = parentWorld.getScaling(); LOGGER.warning("Parent transform: " + parentWorld); // invert the rotation to get the child rotation parentRotation.inverseLocal(); localDeltaTranslation = parentRotation.mult(deltaTranslation); localDeltaTranslation.multLocal(parentScale); LOGGER.warning("Local delta translation: " + localDeltaTranslation); } translate.addLocal(localDeltaTranslation); rotation.multLocal(deltaRotation); transform.setTranslation(translate); transform.setRotation(rotation); MovableComponent mc = getMovable(cell); if (mc != null) { mc.localMoveRequest(transform); } } lastTranslation.addLocal(deltaTranslation); lastRotation.multLocal(deltaRotation); // if we started a drag, remember to end it if (startedDrag) { endDrag(); } }
/** {@inheritDoc} */ @Override public void setStatus(CellStatus status, boolean increasing) { super.setStatus(status, increasing); WlAvatarCharacter pendingAvatar = null; logger.info("AVATAR RENDERER STATUS " + status + " DIR " + increasing); // If we are increasing to the ACTIVE state, then turn everything on. // Add the listeners to the avatar Cell and set the avatar character if (status == CellStatus.ACTIVE && increasing == true) { BoundsDebugger.getInstance().add(this); if (cellMoveListener != null) { // mc should not be null, but sometimes it seems to be MovableComponent mc = cell.getComponent(MovableComponent.class); if (mc == null) { logger.severe("NULL MovableComponent in avatar " + ((AvatarCell) cell).getName()); } else { mc.removeServerCellMoveListener(cellMoveListener); } cellMoveListener = null; } // If we have not creating the avatar yet, then look for the config // component on the cell. Fetch the avatar configuration. if (avatarCharacter == null) { AvatarConfigComponent configComp = cell.getComponent(AvatarConfigComponent.class); AvatarConfigInfo avatarConfigInfo = null; if (configComp != null) { avatarConfigInfo = configComp.getAvatarConfigInfo(); } logger.info("LOADING AVATAR FOR " + avatarConfigInfo); pendingAvatar = loadAvatar(avatarConfigInfo); } else { // Otherwise remove the existing avatar from the world ClientContextJME.getWorldManager().removeEntity(avatarCharacter); pendingAvatar = null; } // Go ahead and change the avatar logger.info("CHANGING AVATAR IN SET STATUS"); changeAvatar(pendingAvatar); if (cellMoveListener == null) { cellMoveListener = new CellMoveListener() { public void cellMoved(CellTransform transform, CellMoveSource source) { if (source == CellMoveSource.REMOTE) { // System.err.println("REMOTE MOVE // "+transform.getTranslation(null)); if (avatarCharacter != null) { if (avatarCharacter.getModelInst() == null) { // Extra debug check logger.severe("MODEL INST IS NULL !"); Thread.dumpStack(); return; } if (delayedMove != null) { delayedMove = null; logger.fine( cell.getCellID() + ": remove delayed move for: " + transform.toString()); } avatarCharacter .getModelInst() .setTransform( new PTransform( transform.getRotation(null), transform.getTranslation(null), new Vector3f(1, 1, 1))); } else { logger.fine(cell.getCellID() + ": delaying move: " + transform.toString()); // we tried to move before loading the avatar. // record the new position to apply when we // actually load delayedMove = transform; } } } }; } cell.getComponent(MovableComponent.class).addServerCellMoveListener(cellMoveListener); avatarUIEventListener = new AvatarUIEventListener(); ClientContext.getInputManager().addGlobalEventListener(avatarUIEventListener); collisionChangeRequestListener = new CollisionChangeRequestListener(); ClientContext.getInputManager().addGlobalEventListener(collisionChangeRequestListener); } else if (status == CellStatus.DISK && !increasing) { BoundsDebugger.getInstance().remove(this); ClientContext.getInputManager().removeGlobalEventListener(avatarUIEventListener); ClientContext.getInputManager().removeGlobalEventListener(collisionChangeRequestListener); cell.getComponent(MovableComponent.class).removeServerCellMoveListener(cellMoveListener); avatarUIEventListener = null; cellMoveListener = null; collisionChangeRequestListener = null; } }