Browse Source

fixed player movement for desktop (player rig)

master
Cailean Finn 2 weeks ago
parent
commit
6375da7a74
  1. 61
      js/ItemManager.js
  2. 56
      js/Player.js
  3. 5
      js/main.js

61
js/ItemManager.js

@ -283,65 +283,4 @@ export class ItemManager {
this._updateGroupCentres();
this._updateInterGroupLinks();
}
// _createLinkLines() {
// this.itemData.forEach(item => {
// if (!item.links) return;
// item.links.forEach(linkedItemId => {
// // Goes through each connection; links = [0, 1, 2..]
// const linkedItem = this.itemData.get(linkedItemId);
// if (!linkedItem) return;
// if (item.groupId !== linkedItem.groupId) return;
// // Creates a key for the Set; a Set can only have unique values, so used for no overlap
// const key = [item.id, linkedItemId].sort().join('-');
// if (this.drawnLinks.has(key)) return;
// const material = new THREE.LineDashedMaterial({
// color: 0xffa500,
// dashSize: 10,
// gapSize: 1
// });
// const sourcePos = item.spawnPosition.clone();
// const terminalPos = linkedItem.spawnPosition.clone();
// sourcePos.y = 1; terminalPos.y = 1;
// const points = [item.spawnPosition.clone(), linkedItem.spawnPosition.clone()];
// const geometry = new THREE.BufferGeometry().setFromPoints(points);
// const line = new THREE.Line(geometry, material);
// line.computeLineDistances();
// this.scene.add(line);
// // The Set is used as the key "0-1", then the item and the linkedItem are set as values in the Map?
// this.linkLines.set(key, { line, item1: item, item2: linkedItem });
// // Make sure it is not drawn again, adding the unique pair here
// this.drawnLinks.add(key);
// });
// });
// }
// _updateLinkLines() {
// this.linkLines.forEach(link => {
// const { line, item1, item2 } = link;
// // Only update/show the line if both items are loaded
// if ((item1.loadState === 'loaded' && item2.loadState === 'loaded')
// && (item1.isVisible && item2.isVisible)) {
// line.visible = true;
// const positions = line.geometry.attributes.position;
// positions.setXYZ(0, item1.object.position.x, 1, item1.object.position.z);
// positions.setXYZ(1, item2.object.position.x, 1, item2.object.position.z);
// positions.needsUpdate = true;
// } else {
// line.visible = false;
// }
// });
// }
}

56
js/Player.js

@ -85,13 +85,13 @@ export class Player {
this.attachedItem = null;
// Update player's position and rotation to match the camera's current state
this.position.copy(this.camera.position);
this.rotation.setFromQuaternion(this.camera.quaternion, 'YXZ');
this.position.copy(this.playerRig.position);
this.rotation.setFromQuaternion(this.playerRig.quaternion, 'YXZ');
} else if(e.code == 'KeyF' && this.currentIntItem && !this.attachedItem){
this.attachedItem = this.currentIntItem;
this.attachedItem.isActive = true;
//console.log("Attached item to player: ", this.attachedItem.object.name);
console.log("Attached item to player: ", this.attachedItem.object.name);
}
if (e.code === 'Space' && this.attachedItem) {
@ -463,7 +463,7 @@ export class Player {
ray.ray.direction.set(0, 0, -1).applyMatrix4(new THREE.Matrix4().extractRotation(controllerMatrix));
} else {
// Use camera for desktop interaction ray
ray.set(this.camera.position, this.camera.getWorldDirection(new THREE.Vector3()));
ray.setFromCamera({ x: 0, y: 0 }, this.camera);
}
const nearbyItems = this.itemList.filter(item => item.object && this.position.distanceTo(item.object.position) < this.maxInteractionDistance);
@ -473,17 +473,22 @@ export class Player {
const intersects = ray.intersectObjects(itemObj, true);
if (intersects.length > 0) {
const intersected = intersects[0].object;
// Find the item whose object contains the intersected mesh
const foundItem = nearbyItems.find(item => {
let found = false;
item.object.traverse(child => {
if (child === intersected) found = true;
});
return found;
});
let intersectedObject = intersects[0].object;
// Traverse up to find the root object that is in our itemObj list
let rootObject = intersectedObject;
while (rootObject.parent && itemObj.indexOf(rootObject) === -1) {
rootObject = rootObject.parent;
}
// Find the item that corresponds to this root object
const foundItem = nearbyItems.find(item => item.object === rootObject);
if (foundItem) {
if (this.currentIntItem !== foundItem) {
// Optional: Add some visual feedback for the newly highlighted item
console.log("Hovering over:", foundItem.object.name);
}
this.currentIntItem = foundItem;
} else {
this.currentIntItem = null;
@ -497,16 +502,26 @@ export class Player {
const itemCenter = new THREE.Vector3();
new THREE.Box3().setFromObject(this.attachedItem.object).getCenter(itemCenter);
const forward = new THREE.Vector3(0, 0, -1).applyQuaternion(this.camera.quaternion);
const targetPosition = itemCenter.clone().add(forward.multiplyScalar(2));
// Get the camera's world position to correctly calculate the lookAt matrix
const cameraWorldPosition = new THREE.Vector3();
this.camera.getWorldPosition(cameraWorldPosition);
// Calculate the desired distance from the object
const forward = new THREE.Vector3(0, 0, -1).applyQuaternion(this.playerRig.quaternion);
const desiredCameraPosition = itemCenter.clone().add(forward.multiplyScalar(2));
this.camera.position.lerp(targetPosition, 0.1);
// Calculate the target position for the rig by subtracting the camera's local offset
// from the desired world position of the camera.
const targetPosition = desiredCameraPosition.clone().sub(this.camera.position);
this.playerRig.position.lerp(targetPosition, 0.1);
// The target rotation should make the camera (not the rig) look at the item center.
const targetRotation = new THREE.Quaternion().setFromRotationMatrix(
new THREE.Matrix4().lookAt(this.camera.position, itemCenter, this.camera.up)
new THREE.Matrix4().lookAt(cameraWorldPosition, itemCenter, this.playerRig.up)
);
this.camera.quaternion.slerp(targetRotation, 0.1);
this.playerRig.quaternion.slerp(targetRotation, 0.1);
}
_updatePlayerMovement(delta) {
@ -516,7 +531,7 @@ export class Player {
this.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, this.rotation.x));
// Only update rotation here. Position will be updated in the main loop after the physics step.
this.camera.rotation.copy(this.rotation);
this.playerRig.rotation.copy(this.rotation);
let direction = new THREE.Vector3();
if (this.input.forward) direction.z -= 1;
@ -531,6 +546,7 @@ export class Player {
move.applyEuler(this.rotation);
move.multiplyScalar(this.moveSpeed * delta);
// Updating the position of the RB based on the position calcuted by Rapier
const newPosition = this.position.clone().add(move);
if( newPosition.y <= 10 ) newPosition.y = 10;
@ -540,7 +556,7 @@ export class Player {
}
update(delta, spawnedObjects) {
//console.log(`Number of Controllers: ${this.vrControllers.length}`);
if (this.renderer.xr.isPresenting) {
this._handleVRJoystick();
this._handleVRTeleport(spawnedObjects);

5
js/main.js

@ -83,9 +83,7 @@ async function init() {
player = new Player(rapierWorld, renderer, scene, new THREE.Vector3(0, 1, 0), interactableItems);
player._setupVR(renderer);
scene.add(player.playerRig);
//scene.add(player.camera);
scene.add(player.playerRig);;
setupSocketIO();
@ -153,7 +151,6 @@ async function animate() {
// (2) Run a step of the physics sim
rapierWorld.step();
// // (3) Update the camera position, after physics step has run.
const newPosition = player.rigibody.translation();

Loading…
Cancel
Save