@soonspacejs/plugin-first-person-controls 2.5.8 → 2.5.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +28 -2
- package/dist/index.esm.js +1 -1
- package/dist/index.js +1 -1
- package/dist-ori/index.d.ts +57 -0
- package/dist-ori/index.esm.js +331 -0
- package/dist-ori/index.esm.js.map +1 -0
- package/example-ori/index.html +109 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -34,10 +34,23 @@ export interface StartOptions {
|
|
|
34
34
|
* 重力搜索系数 表示 向下搜索多少个 eyeHeight 的深度
|
|
35
35
|
*/
|
|
36
36
|
gravitySearchFactor?: number;
|
|
37
|
+
/**
|
|
38
|
+
* 反向旋转
|
|
39
|
+
*/
|
|
40
|
+
reverseRotate?: boolean | null;
|
|
37
41
|
}
|
|
38
42
|
export default class FirstPersonControlsPlugin {
|
|
39
43
|
ssp: SoonSpace;
|
|
40
|
-
|
|
44
|
+
protected _camera: PerspectiveCamera | null;
|
|
45
|
+
/**
|
|
46
|
+
* 是否是外部的相机
|
|
47
|
+
*/
|
|
48
|
+
isExternalCamera: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* 摄像机
|
|
51
|
+
*/
|
|
52
|
+
get camera(): PerspectiveCamera;
|
|
53
|
+
set camera(value: PerspectiveCamera);
|
|
41
54
|
viewport: SoonSpace['viewport'];
|
|
42
55
|
enabled: boolean;
|
|
43
56
|
rotationAngle: {
|
|
@@ -76,15 +89,28 @@ export default class FirstPersonControlsPlugin {
|
|
|
76
89
|
jumpHeight: number;
|
|
77
90
|
enableClash: boolean;
|
|
78
91
|
enableGravity: boolean;
|
|
92
|
+
/**
|
|
93
|
+
* 反向旋转
|
|
94
|
+
*/
|
|
95
|
+
reverseRotate: boolean;
|
|
79
96
|
readonly velocity: Vector3;
|
|
80
97
|
readonly vector: Vector3;
|
|
81
98
|
readonly movement: Vector2;
|
|
82
|
-
|
|
99
|
+
/**
|
|
100
|
+
*
|
|
101
|
+
* @param ssp
|
|
102
|
+
* @param camera - 自定义的摄像机,默认会自动生成一个新的摄像机
|
|
103
|
+
*/
|
|
104
|
+
constructor(ssp: SoonSpace, camera?: PerspectiveCamera | null);
|
|
83
105
|
onKeyDown(event: KeyboardEvent): void;
|
|
84
106
|
onKeyUp(event: KeyboardEvent): void;
|
|
85
107
|
onMouseDown(event: MouseEvent): void;
|
|
86
108
|
onMouseUp(event: MouseEvent): void;
|
|
87
109
|
onMouseMove(event: MouseEvent): void;
|
|
110
|
+
protected _touch: Touch | null;
|
|
111
|
+
onTouchStart(event: TouchEvent): void;
|
|
112
|
+
onTouchEnd(event: TouchEvent): void;
|
|
113
|
+
onTouchMove(event: TouchEvent): void;
|
|
88
114
|
clearClashCache(): void;
|
|
89
115
|
lastDirection: Vector3;
|
|
90
116
|
onClashCheck(origin: Vector3, direction: Vector3): boolean;
|
package/dist/index.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
let e=performance.now();let t;class s{constructor(e){this.gravitySpeed=100,this.jumpOffset=0,this.clashCheckDistance=200,this.clashDistance=50,this.searchRadiusFactor=3,this.checkedObjects=null,this.sceneObjectsChanged=()=>{this.checkedObjects=null},this.gravitySearchFactor=3,this.gravityCheckedObjects=null,this.gravityInterObject=null,this.kneeInterObject=null,this.eyeInterObject=null,this.hasUpdated=!1,this.ssp=e,this.viewport=e.viewport,this.camera=this.viewport.cameraManager.createCamera("firstPersonCamera"),this.enabled=!1,this.rotationAngle={min:-Math.PI/2,max:Math.PI/2},this.state={moveForward:!1,moveBackward:!1,moveLeft:!1,moveRight:!1,moveUp:!1,moveDown:!1,canJump:!1,canRotate:!1},this.moveSpeed=100,this.eyeHeight=160,this.kneeHeight=50,this.jumpHeight=110,this.enableClash=!0,this.enableGravity=!0,this.onKeyDown=this.onKeyDown.bind(this),this.onKeyUp=this.onKeyUp.bind(this),this.onMouseDown=this.onMouseDown.bind(this),this.onMouseUp=this.onMouseUp.bind(this),this.onMouseMove=this.onMouseMove.bind(this);const t=this.ssp.THREE,{Vector3:s,Sphere:i,Vector2:a,Box3:n}=t;this.velocity=new s,this.vector=new s,this.movement=new a,this.lastDirection=new s,this.checkedSphere=new i,this.gravityCheckedBox=new n}onKeyDown(e){if(!1!==this.enabled){switch(e.code){case"ArrowUp":case"KeyW":this.state.moveForward=!0;break;case"ArrowLeft":case"KeyA":this.state.moveLeft=!0;break;case"ArrowDown":case"KeyS":this.state.moveBackward=!0;break;case"ArrowRight":case"KeyD":this.state.moveRight=!0;break;case"KeyI":this.state.canRotate=!0,this.movement.x=0,this.movement.y=-10;break;case"KeyJ":this.state.canRotate=!0,this.movement.x=-10,this.movement.y=0;break;case"KeyK":this.state.canRotate=!0,this.movement.x=0,this.movement.y=10;break;case"KeyL":this.state.canRotate=!0,this.movement.x=10,this.movement.y=0;break;case"KeyQ":this.state.moveUp=!0;break;case"KeyE":this.state.moveDown=!0;break;case"Space":!0===this.state.canJump&&(this.jumpOffset+=3*this.jumpHeight),this.state.canJump=!1}(this.jumpOffset||Object.values(this.state).some((e=>e)))&&this.needUpdate()}}onKeyUp(e){if(!1!==this.enabled)switch(e.code){case"ArrowUp":case"KeyW":this.state.moveForward=!1;break;case"ArrowLeft":case"KeyA":this.state.moveLeft=!1;break;case"ArrowDown":case"KeyS":this.state.moveBackward=!1;break;case"ArrowRight":case"KeyD":this.state.moveRight=!1;break;case"KeyI":case"KeyJ":case"KeyK":case"KeyL":this.state.canRotate=!1;break;case"KeyQ":this.state.moveUp=!1;break;case"KeyE":this.state.moveDown=!1}}onMouseDown(e){this.state.canRotate=!0}onMouseUp(e){this.state.canRotate=!1}onMouseMove(e){if(this.enabled&&this.state.canRotate){const t=e.movementY;let s=e.movementX;0===s&&(e.clientX<20?s=-10:e.clientX>this.viewport.interactiveContainer.clientWidth-20&&(s=10)),this.movement.x=s,this.movement.y=t,this.needUpdate()}}clearClashCache(){this.kneeInterObject=null,this.eyeInterObject=null}onClashCheck(e,t){const s=t.length(),i=t.clone().divideScalar(s);i.distanceToSquared(this.lastDirection)>1e-9&&this.clearClashCache(),this.lastDirection=i;const a=this.ssp.THREE,{eyeHeight:n,kneeHeight:o,camera:c,clashCheckDistance:h,clashDistance:r}=this;let{kneeInterObject:l,eyeInterObject:m}=this;if(!l){const t=e.clone().setY(e.y-n+o),s=new this.ssp.THREE.Raycaster(t,i,0,h);s.camera=c;const a=this.getCheckedObjects(t),r=s.intersectObjects(a);this.kneeInterObject=l=r[0]}let d=-s;if(l&&(d+=l.distance,d<r))return!0;if(!m){const t=new a.Raycaster(e,i,0,h);t.camera=c;const s=this.getCheckedObjects(e),n=t.intersectObjects(s);this.eyeInterObject=m=n[0]}let p=-s;if(m){if(p+=m.distance,p<r)return!0;m.distance=p}return l&&(l.distance=d),!1}getCheckedObjects(e){const{clashDistance:t,clashCheckDistance:s,searchRadiusFactor:i}=this,a=s*i,n=this.checkedSphere;let o=this.checkedObjects;if(o){e.distanceTo(n.center)>a&&(o=null)}if(!o){const s=a+t;n.set(e,s);const i=this.viewport.scener.intersectsList.getAll();this.checkedObjects=o=i.filter((e=>{const t=e.geometry;if(!t)return!0;let s=t.boundingBox;return s||(t.computeBoundingBox(),s=t.boundingBox),!s||n.intersectsBox(s)}))}return o}getGravityCheckedObjects(e,t){const s=this.gravityCheckedBox;let i=this.gravityCheckedObjects;if(i){const a=e.clone();a.y=t,s.containsPoint(e)&&s.containsPoint(a)||(i=null)}if(!i){const{eyeHeight:t,clashCheckDistance:a,gravitySearchFactor:n,clashDistance:o}=this,c=a+o,h=new this.ssp.THREE.Vector3(c,c,0),r=e.clone().add(h),l=e.clone().sub(h);l.y-=t*n,s.set(l,r);const m=this.viewport.scener.intersectsList.getAll();this.checkedObjects=i=m.filter((e=>{const t=e.geometry;if(!t)return!0;let i=t.boundingBox;return i||(t.computeBoundingBox(),i=t.boundingBox),!i||s.intersectsBox(i)}))}return i}gravityClashCheck(e,t){var s;let i=this.gravityInterObject;if(i){const{Vector3:t}=this.ssp.THREE,{object:a,face:n}=i,o=null===(s=a.geometry)||void 0===s?void 0:s.getAttribute("position");if(o&&n){let s=i.facePoints;if(!s){const e=a.matrixWorld,{a:c,b:h,c:r}=n,l=new t(o.getX(c),o.getY(c),o.getZ(c));l.applyMatrix4(e),l.setY(0);const m=new t(o.getX(h),o.getY(h),o.getZ(h));m.applyMatrix4(e),m.setY(0);const d=new t(o.getX(r),o.getY(r),o.getZ(r));d.applyMatrix4(e),d.setY(0),i.facePoints=s=[l,m,d]}let c=s[2],h=null;const r=e.clone();r.y=0;s.every((e=>{const t=e.clone();t.sub(c);const s=r.clone();if(s.sub(c),t.cross(s),h){if(t.dot(h)<=0)return!1}return h=t,c=e,!0}))||(this.gravityInterObject=i=null)}}if(!i){const s=new THREE.Raycaster(e,new THREE.Vector3(0,-1,0));s.camera=this.camera;const a=this.getGravityCheckedObjects(e,t),n=s.intersectObjects(a);this.gravityInterObject=i=n[0]}return i}start(e){const{position:s,rotation:i={x:0,y:0,z:0},moveSpeed:a,eyeHeight:n,kneeHeight:o,jumpHeight:c,enableClash:h,enableGravity:r,searchRadiusFactor:l,clashDistance:m,clashCheckDistance:d,gravitySpeed:p,gravitySearchFactor:v}=e;t=this.ssp.getCameraViewpoint(),this.viewport.controls.currentControls.enabled=!1,this.enabled=!0,n&&(this.eyeHeight=n),o&&(this.kneeHeight=o),c&&(this.jumpHeight=c),l&&(this.searchRadiusFactor=l),m&&(this.clashDistance=m),d&&(this.clashCheckDistance=d),p&&(this.gravitySpeed=p),v&&(this.gravitySearchFactor=v),this.enableClash=null==h||h,this.enableGravity=null==r||r,this.viewport.cameraManager.setCurrentCamera(this.camera),this.camera.position.set(s.x,s.y+this.eyeHeight,s.z),this.camera.rotation.set(i.x,i.y,i.z),a&&(this.moveSpeed=a),this.ssp.signals.cameraChange.dispatch(this.camera.position.clone()),this.viewport.postRender.set("FirstPersonControls",this.update.bind(this)),this.ssp.signals.mouseDown.add(this.onMouseDown),this.ssp.signals.mouseUp.add(this.onMouseUp),this.ssp.signals.mouseMove.add(this.onMouseMove),this.ssp.signals.keyDown.add(this.onKeyDown),this.ssp.signals.keyUp.add(this.onKeyUp),this.ssp.signals.objectAdded.add(this.sceneObjectsChanged),this.ssp.signals.objectRemoved.add(this.sceneObjectsChanged)}stop(){t&&this.ssp.setCameraViewpoint(t),this.viewport.controls.currentControls.enabled=!0,this.enabled=!1,this.viewport.cameraManager.setCurrentCamera(this.viewport.cameraManager.getMainCamera()),this.viewport.postRender.delete("FirstPersonControls"),this.ssp.signals.mouseDown.remove(this.onMouseDown),this.ssp.signals.mouseUp.remove(this.onMouseUp),this.ssp.signals.mouseMove.remove(this.onMouseMove),this.ssp.signals.keyDown.remove(this.onKeyDown),this.ssp.signals.keyUp.remove(this.onKeyUp),this.ssp.signals.objectAdded.remove(this.sceneObjectsChanged),this.ssp.signals.objectRemoved.remove(this.sceneObjectsChanged),this.needUpdate()}needUpdate(){this.hasUpdated&&(this.hasUpdated=!1,e=performance.now(),this.ssp.signals.cameraChange.dispatch(this.camera.position.clone()))}update(){if(!this.enabled)return;const t=performance.now(),s=(t-e)/1e3;e=t;const i=this.ssp.THREE,{Vector3:a}=i,n=new i.Vector3,{gravitySpeed:o,moveSpeed:c,state:h,camera:r,eyeHeight:l}=this,{position:m,quaternion:d}=r;let p=0,v=!1;h.moveForward&&(n.z-=c),h.moveBackward&&(n.z+=c),h.moveLeft&&(n.x-=c),h.moveRight&&(n.x+=c),h.moveUp&&(p+=c),h.moveDown&&(p-=c),n.multiplyScalar(s);const y=new i.Euler(0,0,0,"YXZ");y.setFromQuaternion(d);const u=this.movement;if(h.canRotate&&!u.equals(new i.Vector2)){y.x-=.003*this.movement.y,y.y-=.003*this.movement.x;const{max:e,min:t}=this.rotationAngle;y.x=Math.min(e,Math.max(y.x,t)),r.quaternion.setFromEuler(y),v=!0}const g=this.jumpOffset+p*s;if(0!==y.y&&!n.equals(new a)){const e=new i.Quaternion;e.setFromAxisAngle(new a(0,1,0),y.y),n.applyQuaternion(e)}const b=m.clone();!g&&n.equals(new a)||(n.y+=g,this.onClashCheck(m,n)||b.add(n));let w=b.y;if(this.enableGravity){const e=w;w-=o*s,h.canJump=!1;const t=this.gravityClashCheck(b,w);if(t){const e=t.point.y+l;w<e&&(w=e,h.canJump=!0)}e!==w&&this.clearClashCache()}b.y=w;const k=!m.equals(b);k&&r.position.copy(b),this.jumpOffset=0,(k||v)&&this.ssp.signals.cameraChange.dispatch(this.camera.position.clone()),this.hasUpdated=!0}}export{s as default};
|
|
1
|
+
let e=performance.now();let t;class s{constructor(e,t){this._camera=null,this.isExternalCamera=!1,this.gravitySpeed=100,this.jumpOffset=0,this.clashCheckDistance=200,this.clashDistance=50,this.reverseRotate=!1,this._touch=null,this.searchRadiusFactor=3,this.checkedObjects=null,this.sceneObjectsChanged=()=>{this.checkedObjects=null},this.gravitySearchFactor=3,this.gravityCheckedObjects=null,this.gravityInterObject=null,this.kneeInterObject=null,this.eyeInterObject=null,this.hasUpdated=!1,this.ssp=e,this._camera=null!=t?t:null,this.viewport=e.viewport,this.enabled=!1,this.rotationAngle={min:-Math.PI/2,max:Math.PI/2},this.state={moveForward:!1,moveBackward:!1,moveLeft:!1,moveRight:!1,moveUp:!1,moveDown:!1,canJump:!1,canRotate:!1},this.moveSpeed=100,this.eyeHeight=160,this.kneeHeight=50,this.jumpHeight=110,this.enableClash=!0,this.enableGravity=!0,this.onKeyDown=this.onKeyDown.bind(this),this.onKeyUp=this.onKeyUp.bind(this),this.onMouseDown=this.onMouseDown.bind(this),this.onMouseUp=this.onMouseUp.bind(this),this.onMouseMove=this.onMouseMove.bind(this),this.onTouchStart=this.onTouchStart.bind(this),this.onTouchMove=this.onTouchMove.bind(this),this.onTouchEnd=this.onTouchEnd.bind(this);const s=this.ssp.THREE,{Vector3:i,Sphere:n,Vector2:a,Box3:o}=s;this.velocity=new i,this.vector=new i,this.movement=new a,this.lastDirection=new i,this.checkedSphere=new n,this.gravityCheckedBox=new o}get camera(){let e=this._camera;return e||(e=this._camera=this.viewport.cameraManager.createCamera("firstPersonCamera"),this.isExternalCamera=!1),e}set camera(e){this._camera=e,this.isExternalCamera=!0}onKeyDown(e){if(!1!==this.enabled){switch(e.code){case"ArrowUp":case"KeyW":this.state.moveForward=!0;break;case"ArrowLeft":case"KeyA":this.state.moveLeft=!0;break;case"ArrowDown":case"KeyS":this.state.moveBackward=!0;break;case"ArrowRight":case"KeyD":this.state.moveRight=!0;break;case"KeyI":this.state.canRotate=!0,this.movement.x=0,this.movement.y=-10;break;case"KeyJ":this.state.canRotate=!0,this.movement.x=-10,this.movement.y=0;break;case"KeyK":this.state.canRotate=!0,this.movement.x=0,this.movement.y=10;break;case"KeyL":this.state.canRotate=!0,this.movement.x=10,this.movement.y=0;break;case"KeyQ":this.state.moveUp=!0;break;case"KeyE":this.state.moveDown=!0;break;case"Space":!0===this.state.canJump&&(this.jumpOffset+=3*this.jumpHeight),this.state.canJump=!1}(this.jumpOffset||Object.values(this.state).some((e=>e)))&&this.needUpdate()}}onKeyUp(e){if(!1!==this.enabled)switch(e.code){case"ArrowUp":case"KeyW":this.state.moveForward=!1;break;case"ArrowLeft":case"KeyA":this.state.moveLeft=!1;break;case"ArrowDown":case"KeyS":this.state.moveBackward=!1;break;case"ArrowRight":case"KeyD":this.state.moveRight=!1;break;case"KeyI":case"KeyJ":case"KeyK":case"KeyL":this.state.canRotate=!1;break;case"KeyQ":this.state.moveUp=!1;break;case"KeyE":this.state.moveDown=!1}}onMouseDown(e){this.state.canRotate=!0}onMouseUp(e){this.state.canRotate=!1}onMouseMove(e){if(this.enabled&&this.state.canRotate){let t=e.movementY,s=e.movementX;0===s&&(e.clientX<20?s=-10:e.clientX>this.viewport.interactiveContainer.clientWidth-20&&(s=10)),this.reverseRotate&&(s=-s,t=-t),this.movement.x=s,this.movement.y=t,this.needUpdate()}}onTouchStart(e){this._touch=e.targetTouches[0],this._touch&&(this.state.canRotate=!0)}onTouchEnd(e){const t=this._touch;if(!t)return;if(e.targetTouches.length>0){if(!Array.from(e.targetTouches).find((e=>e.identifier===t.identifier)))return}this._touch=null,this.state.canRotate=!1}onTouchMove(e){const t=this._touch;if(!t)return;const s=Array.from(e.targetTouches).find((e=>e.identifier===t.identifier));if(!s)return;if(!this.enabled||!this.state.canRotate)return;let i=s.screenX-t.screenX,n=s.screenY-t.screenY;0===i&&(s.clientX<20?i=-10:s.clientX>this.viewport.interactiveContainer.clientWidth-20&&(i=10)),this.reverseRotate&&(i=-i,n=-n),this.movement.x=i,this.movement.y=n,this._touch=s,this.needUpdate()}clearClashCache(){this.kneeInterObject=null,this.eyeInterObject=null}onClashCheck(e,t){const s=t.length(),i=t.clone().divideScalar(s);i.distanceToSquared(this.lastDirection)>1e-9&&this.clearClashCache(),this.lastDirection=i;const n=this.ssp.THREE,{eyeHeight:a,kneeHeight:o,camera:h,clashCheckDistance:c,clashDistance:r}=this;let{kneeInterObject:l,eyeInterObject:m}=this;if(!l){const t=e.clone().setY(e.y-a+o),s=new this.ssp.THREE.Raycaster(t,i,0,c);s.camera=h;const n=this.getCheckedObjects(t),r=s.intersectObjects(n);this.kneeInterObject=l=r[0]}let d=-s;if(l&&(d+=l.distance,d<r))return!0;if(!m){const t=new n.Raycaster(e,i,0,c);t.camera=h;const s=this.getCheckedObjects(e),a=t.intersectObjects(s);this.eyeInterObject=m=a[0]}let u=-s;if(m){if(u+=m.distance,u<r)return!0;m.distance=u}return l&&(l.distance=d),!1}getCheckedObjects(e){const{clashDistance:t,clashCheckDistance:s,searchRadiusFactor:i}=this,n=s*i,a=this.checkedSphere;let o=this.checkedObjects;if(o){e.distanceTo(a.center)>n&&(o=null)}if(!o){const s=n+t;a.set(e,s);const i=this.viewport.scener.intersectsList.getAll();this.checkedObjects=o=i.filter((e=>{const t=e.geometry;if(!t)return!0;let s=t.boundingBox;return s||(t.computeBoundingBox(),s=t.boundingBox),!s||a.intersectsBox(s)}))}return o}getGravityCheckedObjects(e,t){const s=this.gravityCheckedBox;let i=this.gravityCheckedObjects;if(i){const n=e.clone();n.y=t,s.containsPoint(e)&&s.containsPoint(n)||(i=null)}if(!i){const{eyeHeight:t,clashCheckDistance:n,gravitySearchFactor:a,clashDistance:o}=this,h=n+o,c=new this.ssp.THREE.Vector3(h,h,0),r=e.clone().add(c),l=e.clone().sub(c);l.y-=t*a,s.set(l,r);const m=this.viewport.scener.intersectsList.getAll();this.checkedObjects=i=m.filter((e=>{const t=e.geometry;if(!t)return!0;let i=t.boundingBox;return i||(t.computeBoundingBox(),i=t.boundingBox),!i||s.intersectsBox(i)}))}return i}gravityClashCheck(e,t){var s;let i=this.gravityInterObject;if(i){const{Vector3:t}=this.ssp.THREE,{object:n,face:a}=i,o=null===(s=n.geometry)||void 0===s?void 0:s.getAttribute("position");if(o&&a){let s=i.facePoints;if(!s){const e=n.matrixWorld,{a:h,b:c,c:r}=a,l=new t(o.getX(h),o.getY(h),o.getZ(h));l.applyMatrix4(e),l.setY(0);const m=new t(o.getX(c),o.getY(c),o.getZ(c));m.applyMatrix4(e),m.setY(0);const d=new t(o.getX(r),o.getY(r),o.getZ(r));d.applyMatrix4(e),d.setY(0),i.facePoints=s=[l,m,d]}let h=s[2],c=null;const r=e.clone();r.y=0;s.every((e=>{const t=e.clone();t.sub(h);const s=r.clone();if(s.sub(h),t.cross(s),c){if(t.dot(c)<=0)return!1}return c=t,h=e,!0}))||(this.gravityInterObject=i=null)}}if(!i){const s=new THREE.Raycaster(e,new THREE.Vector3(0,-1,0));s.camera=this.camera;const n=this.getGravityCheckedObjects(e,t),a=s.intersectObjects(n);this.gravityInterObject=i=a[0]}return i}start(e){const{position:s,rotation:i={x:0,y:0,z:0},moveSpeed:n,eyeHeight:a,kneeHeight:o,jumpHeight:h,enableClash:c,enableGravity:r,searchRadiusFactor:l,clashDistance:m,clashCheckDistance:d,gravitySpeed:u,gravitySearchFactor:p,reverseRotate:v}=e;t=this.ssp.getCameraViewpoint(),this.viewport.controls.currentControls.enabled=!1,this.enabled=!0,a&&(this.eyeHeight=a),o&&(this.kneeHeight=o),h&&(this.jumpHeight=h),l&&(this.searchRadiusFactor=l),m&&(this.clashDistance=m),d&&(this.clashCheckDistance=d),u&&(this.gravitySpeed=u),p&&(this.gravitySearchFactor=p),v&&(this.reverseRotate=v),this.enableClash=null==c||c,this.enableGravity=null==r||r,this.isExternalCamera||this.viewport.cameraManager.setCurrentCamera(this.camera),this.camera.position.set(s.x,s.y+this.eyeHeight,s.z),this.camera.rotation.set(i.x,i.y,i.z),n&&(this.moveSpeed=n),this.ssp.signals.cameraChange.dispatch(this.camera.position.clone()),this.viewport.postRender.set("FirstPersonControls",this.update.bind(this)),this.ssp.signals.mouseDown.add(this.onMouseDown),this.ssp.signals.mouseUp.add(this.onMouseUp),this.ssp.signals.mouseMove.add(this.onMouseMove),this.ssp.signals.keyDown.add(this.onKeyDown),this.ssp.signals.keyUp.add(this.onKeyUp);const g=this.ssp.viewport.container;g.addEventListener("touchstart",this.onTouchStart),g.addEventListener("touchmove",this.onTouchMove),g.addEventListener("touchend",this.onTouchEnd),this.ssp.signals.objectAdded.add(this.sceneObjectsChanged),this.ssp.signals.objectRemoved.add(this.sceneObjectsChanged)}stop(){t&&this.ssp.setCameraViewpoint(t),this.viewport.controls.currentControls.enabled=!0,this.enabled=!1,this.viewport.cameraManager.setCurrentCamera(this.viewport.cameraManager.getMainCamera()),this.viewport.postRender.delete("FirstPersonControls"),this.ssp.signals.mouseDown.remove(this.onMouseDown),this.ssp.signals.mouseUp.remove(this.onMouseUp),this.ssp.signals.mouseMove.remove(this.onMouseMove),this.ssp.signals.keyDown.remove(this.onKeyDown),this.ssp.signals.keyUp.remove(this.onKeyUp);const e=this.ssp.viewport.container;e.removeEventListener("touchstart",this.onTouchStart),e.removeEventListener("touchmove",this.onTouchMove),e.removeEventListener("touchend",this.onTouchEnd),this.ssp.signals.objectAdded.remove(this.sceneObjectsChanged),this.ssp.signals.objectRemoved.remove(this.sceneObjectsChanged),this.needUpdate()}needUpdate(){this.hasUpdated&&(this.hasUpdated=!1,e=performance.now(),this.ssp.signals.cameraChange.dispatch(this.camera.position.clone()))}update(){if(!this.enabled)return;const t=performance.now(),s=(t-e)/1e3;e=t;const i=this.ssp.THREE,{Vector3:n}=i,a=new i.Vector3,{gravitySpeed:o,moveSpeed:h,state:c,camera:r,eyeHeight:l}=this,{position:m,quaternion:d}=r;let u=0,p=!1;c.moveForward&&(a.z-=h),c.moveBackward&&(a.z+=h),c.moveLeft&&(a.x-=h),c.moveRight&&(a.x+=h),c.moveUp&&(u+=h),c.moveDown&&(u-=h),a.multiplyScalar(s);const v=new i.Euler(0,0,0,"YXZ");v.setFromQuaternion(d);const g=this.movement;if(c.canRotate&&!g.equals(new i.Vector2)){v.x-=.003*this.movement.y,v.y-=.003*this.movement.x;const{max:e,min:t}=this.rotationAngle;v.x=Math.min(e,Math.max(v.x,t)),r.quaternion.setFromEuler(v),p=!0}const y=this.jumpOffset+u*s;if(0!==v.y&&!a.equals(new n)){const e=new i.Quaternion;e.setFromAxisAngle(new n(0,1,0),v.y),a.applyQuaternion(e)}const b=m.clone();!y&&a.equals(new n)||(a.y+=y,this.onClashCheck(m,a)||b.add(a));let w=b.y;if(this.enableGravity){const e=w;w-=o*s,c.canJump=!1;const t=this.gravityClashCheck(b,w);if(t){const e=t.point.y+l;w<e&&(w=e,c.canJump=!0)}e!==w&&this.clearClashCache()}b.y=w;const f=!m.equals(b);f&&r.position.copy(b),this.jumpOffset=0,(f||p)&&this.ssp.signals.cameraChange.dispatch(this.camera.position.clone()),this.hasUpdated=!0}}export{s as default};
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).FirstPersonControlsPlugin=t()}(this,(function(){"use strict";let e=performance.now();let t;return class{constructor(e){this.gravitySpeed=100,this.jumpOffset=0,this.clashCheckDistance=200,this.clashDistance=50,this.searchRadiusFactor=3,this.checkedObjects=null,this.sceneObjectsChanged=()=>{this.checkedObjects=null},this.gravitySearchFactor=3,this.gravityCheckedObjects=null,this.gravityInterObject=null,this.kneeInterObject=null,this.eyeInterObject=null,this.hasUpdated=!1,this.ssp=e,this.viewport=e.viewport,this.camera=this.viewport.cameraManager.createCamera("firstPersonCamera"),this.enabled=!1,this.rotationAngle={min:-Math.PI/2,max:Math.PI/2},this.state={moveForward:!1,moveBackward:!1,moveLeft:!1,moveRight:!1,moveUp:!1,moveDown:!1,canJump:!1,canRotate:!1},this.moveSpeed=100,this.eyeHeight=160,this.kneeHeight=50,this.jumpHeight=110,this.enableClash=!0,this.enableGravity=!0,this.onKeyDown=this.onKeyDown.bind(this),this.onKeyUp=this.onKeyUp.bind(this),this.onMouseDown=this.onMouseDown.bind(this),this.onMouseUp=this.onMouseUp.bind(this),this.onMouseMove=this.onMouseMove.bind(this);const t=this.ssp.THREE,{Vector3:s,Sphere:i,Vector2:a,Box3:n}=t;this.velocity=new s,this.vector=new s,this.movement=new a,this.lastDirection=new s,this.checkedSphere=new i,this.gravityCheckedBox=new n}onKeyDown(e){if(!1!==this.enabled){switch(e.code){case"ArrowUp":case"KeyW":this.state.moveForward=!0;break;case"ArrowLeft":case"KeyA":this.state.moveLeft=!0;break;case"ArrowDown":case"KeyS":this.state.moveBackward=!0;break;case"ArrowRight":case"KeyD":this.state.moveRight=!0;break;case"KeyI":this.state.canRotate=!0,this.movement.x=0,this.movement.y=-10;break;case"KeyJ":this.state.canRotate=!0,this.movement.x=-10,this.movement.y=0;break;case"KeyK":this.state.canRotate=!0,this.movement.x=0,this.movement.y=10;break;case"KeyL":this.state.canRotate=!0,this.movement.x=10,this.movement.y=0;break;case"KeyQ":this.state.moveUp=!0;break;case"KeyE":this.state.moveDown=!0;break;case"Space":!0===this.state.canJump&&(this.jumpOffset+=3*this.jumpHeight),this.state.canJump=!1}(this.jumpOffset||Object.values(this.state).some((e=>e)))&&this.needUpdate()}}onKeyUp(e){if(!1!==this.enabled)switch(e.code){case"ArrowUp":case"KeyW":this.state.moveForward=!1;break;case"ArrowLeft":case"KeyA":this.state.moveLeft=!1;break;case"ArrowDown":case"KeyS":this.state.moveBackward=!1;break;case"ArrowRight":case"KeyD":this.state.moveRight=!1;break;case"KeyI":case"KeyJ":case"KeyK":case"KeyL":this.state.canRotate=!1;break;case"KeyQ":this.state.moveUp=!1;break;case"KeyE":this.state.moveDown=!1}}onMouseDown(e){this.state.canRotate=!0}onMouseUp(e){this.state.canRotate=!1}onMouseMove(e){if(this.enabled&&this.state.canRotate){const t=e.movementY;let s=e.movementX;0===s&&(e.clientX<20?s=-10:e.clientX>this.viewport.interactiveContainer.clientWidth-20&&(s=10)),this.movement.x=s,this.movement.y=t,this.needUpdate()}}clearClashCache(){this.kneeInterObject=null,this.eyeInterObject=null}onClashCheck(e,t){const s=t.length(),i=t.clone().divideScalar(s);i.distanceToSquared(this.lastDirection)>1e-9&&this.clearClashCache(),this.lastDirection=i;const a=this.ssp.THREE,{eyeHeight:n,kneeHeight:o,camera:c,clashCheckDistance:h,clashDistance:r}=this;let{kneeInterObject:l,eyeInterObject:m}=this;if(!l){const t=e.clone().setY(e.y-n+o),s=new this.ssp.THREE.Raycaster(t,i,0,h);s.camera=c;const a=this.getCheckedObjects(t),r=s.intersectObjects(a);this.kneeInterObject=l=r[0]}let d=-s;if(l&&(d+=l.distance,d<r))return!0;if(!m){const t=new a.Raycaster(e,i,0,h);t.camera=c;const s=this.getCheckedObjects(e),n=t.intersectObjects(s);this.eyeInterObject=m=n[0]}let p=-s;if(m){if(p+=m.distance,p<r)return!0;m.distance=p}return l&&(l.distance=d),!1}getCheckedObjects(e){const{clashDistance:t,clashCheckDistance:s,searchRadiusFactor:i}=this,a=s*i,n=this.checkedSphere;let o=this.checkedObjects;if(o){e.distanceTo(n.center)>a&&(o=null)}if(!o){const s=a+t;n.set(e,s);const i=this.viewport.scener.intersectsList.getAll();this.checkedObjects=o=i.filter((e=>{const t=e.geometry;if(!t)return!0;let s=t.boundingBox;return s||(t.computeBoundingBox(),s=t.boundingBox),!s||n.intersectsBox(s)}))}return o}getGravityCheckedObjects(e,t){const s=this.gravityCheckedBox;let i=this.gravityCheckedObjects;if(i){const a=e.clone();a.y=t,s.containsPoint(e)&&s.containsPoint(a)||(i=null)}if(!i){const{eyeHeight:t,clashCheckDistance:a,gravitySearchFactor:n,clashDistance:o}=this,c=a+o,h=new this.ssp.THREE.Vector3(c,c,0),r=e.clone().add(h),l=e.clone().sub(h);l.y-=t*n,s.set(l,r);const m=this.viewport.scener.intersectsList.getAll();this.checkedObjects=i=m.filter((e=>{const t=e.geometry;if(!t)return!0;let i=t.boundingBox;return i||(t.computeBoundingBox(),i=t.boundingBox),!i||s.intersectsBox(i)}))}return i}gravityClashCheck(e,t){var s;let i=this.gravityInterObject;if(i){const{Vector3:t}=this.ssp.THREE,{object:a,face:n}=i,o=null===(s=a.geometry)||void 0===s?void 0:s.getAttribute("position");if(o&&n){let s=i.facePoints;if(!s){const e=a.matrixWorld,{a:c,b:h,c:r}=n,l=new t(o.getX(c),o.getY(c),o.getZ(c));l.applyMatrix4(e),l.setY(0);const m=new t(o.getX(h),o.getY(h),o.getZ(h));m.applyMatrix4(e),m.setY(0);const d=new t(o.getX(r),o.getY(r),o.getZ(r));d.applyMatrix4(e),d.setY(0),i.facePoints=s=[l,m,d]}let c=s[2],h=null;const r=e.clone();r.y=0;s.every((e=>{const t=e.clone();t.sub(c);const s=r.clone();if(s.sub(c),t.cross(s),h){if(t.dot(h)<=0)return!1}return h=t,c=e,!0}))||(this.gravityInterObject=i=null)}}if(!i){const s=new THREE.Raycaster(e,new THREE.Vector3(0,-1,0));s.camera=this.camera;const a=this.getGravityCheckedObjects(e,t),n=s.intersectObjects(a);this.gravityInterObject=i=n[0]}return i}start(e){const{position:s,rotation:i={x:0,y:0,z:0},moveSpeed:a,eyeHeight:n,kneeHeight:o,jumpHeight:c,enableClash:h,enableGravity:r,searchRadiusFactor:l,clashDistance:m,clashCheckDistance:d,gravitySpeed:p,gravitySearchFactor:u}=e;t=this.ssp.getCameraViewpoint(),this.viewport.controls.currentControls.enabled=!1,this.enabled=!0,n&&(this.eyeHeight=n),o&&(this.kneeHeight=o),c&&(this.jumpHeight=c),l&&(this.searchRadiusFactor=l),m&&(this.clashDistance=m),d&&(this.clashCheckDistance=d),p&&(this.gravitySpeed=p),u&&(this.gravitySearchFactor=u),this.enableClash=null==h||h,this.enableGravity=null==r||r,this.viewport.cameraManager.setCurrentCamera(this.camera),this.camera.position.set(s.x,s.y+this.eyeHeight,s.z),this.camera.rotation.set(i.x,i.y,i.z),a&&(this.moveSpeed=a),this.ssp.signals.cameraChange.dispatch(this.camera.position.clone()),this.viewport.postRender.set("FirstPersonControls",this.update.bind(this)),this.ssp.signals.mouseDown.add(this.onMouseDown),this.ssp.signals.mouseUp.add(this.onMouseUp),this.ssp.signals.mouseMove.add(this.onMouseMove),this.ssp.signals.keyDown.add(this.onKeyDown),this.ssp.signals.keyUp.add(this.onKeyUp),this.ssp.signals.objectAdded.add(this.sceneObjectsChanged),this.ssp.signals.objectRemoved.add(this.sceneObjectsChanged)}stop(){t&&this.ssp.setCameraViewpoint(t),this.viewport.controls.currentControls.enabled=!0,this.enabled=!1,this.viewport.cameraManager.setCurrentCamera(this.viewport.cameraManager.getMainCamera()),this.viewport.postRender.delete("FirstPersonControls"),this.ssp.signals.mouseDown.remove(this.onMouseDown),this.ssp.signals.mouseUp.remove(this.onMouseUp),this.ssp.signals.mouseMove.remove(this.onMouseMove),this.ssp.signals.keyDown.remove(this.onKeyDown),this.ssp.signals.keyUp.remove(this.onKeyUp),this.ssp.signals.objectAdded.remove(this.sceneObjectsChanged),this.ssp.signals.objectRemoved.remove(this.sceneObjectsChanged),this.needUpdate()}needUpdate(){this.hasUpdated&&(this.hasUpdated=!1,e=performance.now(),this.ssp.signals.cameraChange.dispatch(this.camera.position.clone()))}update(){if(!this.enabled)return;const t=performance.now(),s=(t-e)/1e3;e=t;const i=this.ssp.THREE,{Vector3:a}=i,n=new i.Vector3,{gravitySpeed:o,moveSpeed:c,state:h,camera:r,eyeHeight:l}=this,{position:m,quaternion:d}=r;let p=0,u=!1;h.moveForward&&(n.z-=c),h.moveBackward&&(n.z+=c),h.moveLeft&&(n.x-=c),h.moveRight&&(n.x+=c),h.moveUp&&(p+=c),h.moveDown&&(p-=c),n.multiplyScalar(s);const y=new i.Euler(0,0,0,"YXZ");y.setFromQuaternion(d);const v=this.movement;if(h.canRotate&&!v.equals(new i.Vector2)){y.x-=.003*this.movement.y,y.y-=.003*this.movement.x;const{max:e,min:t}=this.rotationAngle;y.x=Math.min(e,Math.max(y.x,t)),r.quaternion.setFromEuler(y),u=!0}const g=this.jumpOffset+p*s;if(0!==y.y&&!n.equals(new a)){const e=new i.Quaternion;e.setFromAxisAngle(new a(0,1,0),y.y),n.applyQuaternion(e)}const b=m.clone();!g&&n.equals(new a)||(n.y+=g,this.onClashCheck(m,n)||b.add(n));let w=b.y;if(this.enableGravity){const e=w;w-=o*s,h.canJump=!1;const t=this.gravityClashCheck(b,w);if(t){const e=t.point.y+l;w<e&&(w=e,h.canJump=!0)}e!==w&&this.clearClashCache()}b.y=w;const f=!m.equals(b);f&&r.position.copy(b),this.jumpOffset=0,(f||u)&&this.ssp.signals.cameraChange.dispatch(this.camera.position.clone()),this.hasUpdated=!0}}}));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).FirstPersonControlsPlugin=t()}(this,(function(){"use strict";let e=performance.now();let t;return class{constructor(e,t){this._camera=null,this.isExternalCamera=!1,this.gravitySpeed=100,this.jumpOffset=0,this.clashCheckDistance=200,this.clashDistance=50,this.reverseRotate=!1,this._touch=null,this.searchRadiusFactor=3,this.checkedObjects=null,this.sceneObjectsChanged=()=>{this.checkedObjects=null},this.gravitySearchFactor=3,this.gravityCheckedObjects=null,this.gravityInterObject=null,this.kneeInterObject=null,this.eyeInterObject=null,this.hasUpdated=!1,this.ssp=e,this._camera=null!=t?t:null,this.viewport=e.viewport,this.enabled=!1,this.rotationAngle={min:-Math.PI/2,max:Math.PI/2},this.state={moveForward:!1,moveBackward:!1,moveLeft:!1,moveRight:!1,moveUp:!1,moveDown:!1,canJump:!1,canRotate:!1},this.moveSpeed=100,this.eyeHeight=160,this.kneeHeight=50,this.jumpHeight=110,this.enableClash=!0,this.enableGravity=!0,this.onKeyDown=this.onKeyDown.bind(this),this.onKeyUp=this.onKeyUp.bind(this),this.onMouseDown=this.onMouseDown.bind(this),this.onMouseUp=this.onMouseUp.bind(this),this.onMouseMove=this.onMouseMove.bind(this),this.onTouchStart=this.onTouchStart.bind(this),this.onTouchMove=this.onTouchMove.bind(this),this.onTouchEnd=this.onTouchEnd.bind(this);const s=this.ssp.THREE,{Vector3:i,Sphere:n,Vector2:a,Box3:o}=s;this.velocity=new i,this.vector=new i,this.movement=new a,this.lastDirection=new i,this.checkedSphere=new n,this.gravityCheckedBox=new o}get camera(){let e=this._camera;return e||(e=this._camera=this.viewport.cameraManager.createCamera("firstPersonCamera"),this.isExternalCamera=!1),e}set camera(e){this._camera=e,this.isExternalCamera=!0}onKeyDown(e){if(!1!==this.enabled){switch(e.code){case"ArrowUp":case"KeyW":this.state.moveForward=!0;break;case"ArrowLeft":case"KeyA":this.state.moveLeft=!0;break;case"ArrowDown":case"KeyS":this.state.moveBackward=!0;break;case"ArrowRight":case"KeyD":this.state.moveRight=!0;break;case"KeyI":this.state.canRotate=!0,this.movement.x=0,this.movement.y=-10;break;case"KeyJ":this.state.canRotate=!0,this.movement.x=-10,this.movement.y=0;break;case"KeyK":this.state.canRotate=!0,this.movement.x=0,this.movement.y=10;break;case"KeyL":this.state.canRotate=!0,this.movement.x=10,this.movement.y=0;break;case"KeyQ":this.state.moveUp=!0;break;case"KeyE":this.state.moveDown=!0;break;case"Space":!0===this.state.canJump&&(this.jumpOffset+=3*this.jumpHeight),this.state.canJump=!1}(this.jumpOffset||Object.values(this.state).some((e=>e)))&&this.needUpdate()}}onKeyUp(e){if(!1!==this.enabled)switch(e.code){case"ArrowUp":case"KeyW":this.state.moveForward=!1;break;case"ArrowLeft":case"KeyA":this.state.moveLeft=!1;break;case"ArrowDown":case"KeyS":this.state.moveBackward=!1;break;case"ArrowRight":case"KeyD":this.state.moveRight=!1;break;case"KeyI":case"KeyJ":case"KeyK":case"KeyL":this.state.canRotate=!1;break;case"KeyQ":this.state.moveUp=!1;break;case"KeyE":this.state.moveDown=!1}}onMouseDown(e){this.state.canRotate=!0}onMouseUp(e){this.state.canRotate=!1}onMouseMove(e){if(this.enabled&&this.state.canRotate){let t=e.movementY,s=e.movementX;0===s&&(e.clientX<20?s=-10:e.clientX>this.viewport.interactiveContainer.clientWidth-20&&(s=10)),this.reverseRotate&&(s=-s,t=-t),this.movement.x=s,this.movement.y=t,this.needUpdate()}}onTouchStart(e){this._touch=e.targetTouches[0],this._touch&&(this.state.canRotate=!0)}onTouchEnd(e){const t=this._touch;if(!t)return;if(e.targetTouches.length>0){if(!Array.from(e.targetTouches).find((e=>e.identifier===t.identifier)))return}this._touch=null,this.state.canRotate=!1}onTouchMove(e){const t=this._touch;if(!t)return;const s=Array.from(e.targetTouches).find((e=>e.identifier===t.identifier));if(!s)return;if(!this.enabled||!this.state.canRotate)return;let i=s.screenX-t.screenX,n=s.screenY-t.screenY;0===i&&(s.clientX<20?i=-10:s.clientX>this.viewport.interactiveContainer.clientWidth-20&&(i=10)),this.reverseRotate&&(i=-i,n=-n),this.movement.x=i,this.movement.y=n,this._touch=s,this.needUpdate()}clearClashCache(){this.kneeInterObject=null,this.eyeInterObject=null}onClashCheck(e,t){const s=t.length(),i=t.clone().divideScalar(s);i.distanceToSquared(this.lastDirection)>1e-9&&this.clearClashCache(),this.lastDirection=i;const n=this.ssp.THREE,{eyeHeight:a,kneeHeight:o,camera:h,clashCheckDistance:c,clashDistance:r}=this;let{kneeInterObject:l,eyeInterObject:d}=this;if(!l){const t=e.clone().setY(e.y-a+o),s=new this.ssp.THREE.Raycaster(t,i,0,c);s.camera=h;const n=this.getCheckedObjects(t),r=s.intersectObjects(n);this.kneeInterObject=l=r[0]}let m=-s;if(l&&(m+=l.distance,m<r))return!0;if(!d){const t=new n.Raycaster(e,i,0,c);t.camera=h;const s=this.getCheckedObjects(e),a=t.intersectObjects(s);this.eyeInterObject=d=a[0]}let u=-s;if(d){if(u+=d.distance,u<r)return!0;d.distance=u}return l&&(l.distance=m),!1}getCheckedObjects(e){const{clashDistance:t,clashCheckDistance:s,searchRadiusFactor:i}=this,n=s*i,a=this.checkedSphere;let o=this.checkedObjects;if(o){e.distanceTo(a.center)>n&&(o=null)}if(!o){const s=n+t;a.set(e,s);const i=this.viewport.scener.intersectsList.getAll();this.checkedObjects=o=i.filter((e=>{const t=e.geometry;if(!t)return!0;let s=t.boundingBox;return s||(t.computeBoundingBox(),s=t.boundingBox),!s||a.intersectsBox(s)}))}return o}getGravityCheckedObjects(e,t){const s=this.gravityCheckedBox;let i=this.gravityCheckedObjects;if(i){const n=e.clone();n.y=t,s.containsPoint(e)&&s.containsPoint(n)||(i=null)}if(!i){const{eyeHeight:t,clashCheckDistance:n,gravitySearchFactor:a,clashDistance:o}=this,h=n+o,c=new this.ssp.THREE.Vector3(h,h,0),r=e.clone().add(c),l=e.clone().sub(c);l.y-=t*a,s.set(l,r);const d=this.viewport.scener.intersectsList.getAll();this.checkedObjects=i=d.filter((e=>{const t=e.geometry;if(!t)return!0;let i=t.boundingBox;return i||(t.computeBoundingBox(),i=t.boundingBox),!i||s.intersectsBox(i)}))}return i}gravityClashCheck(e,t){var s;let i=this.gravityInterObject;if(i){const{Vector3:t}=this.ssp.THREE,{object:n,face:a}=i,o=null===(s=n.geometry)||void 0===s?void 0:s.getAttribute("position");if(o&&a){let s=i.facePoints;if(!s){const e=n.matrixWorld,{a:h,b:c,c:r}=a,l=new t(o.getX(h),o.getY(h),o.getZ(h));l.applyMatrix4(e),l.setY(0);const d=new t(o.getX(c),o.getY(c),o.getZ(c));d.applyMatrix4(e),d.setY(0);const m=new t(o.getX(r),o.getY(r),o.getZ(r));m.applyMatrix4(e),m.setY(0),i.facePoints=s=[l,d,m]}let h=s[2],c=null;const r=e.clone();r.y=0;s.every((e=>{const t=e.clone();t.sub(h);const s=r.clone();if(s.sub(h),t.cross(s),c){if(t.dot(c)<=0)return!1}return c=t,h=e,!0}))||(this.gravityInterObject=i=null)}}if(!i){const s=new THREE.Raycaster(e,new THREE.Vector3(0,-1,0));s.camera=this.camera;const n=this.getGravityCheckedObjects(e,t),a=s.intersectObjects(n);this.gravityInterObject=i=a[0]}return i}start(e){const{position:s,rotation:i={x:0,y:0,z:0},moveSpeed:n,eyeHeight:a,kneeHeight:o,jumpHeight:h,enableClash:c,enableGravity:r,searchRadiusFactor:l,clashDistance:d,clashCheckDistance:m,gravitySpeed:u,gravitySearchFactor:p,reverseRotate:v}=e;t=this.ssp.getCameraViewpoint(),this.viewport.controls.currentControls.enabled=!1,this.enabled=!0,a&&(this.eyeHeight=a),o&&(this.kneeHeight=o),h&&(this.jumpHeight=h),l&&(this.searchRadiusFactor=l),d&&(this.clashDistance=d),m&&(this.clashCheckDistance=m),u&&(this.gravitySpeed=u),p&&(this.gravitySearchFactor=p),v&&(this.reverseRotate=v),this.enableClash=null==c||c,this.enableGravity=null==r||r,this.isExternalCamera||this.viewport.cameraManager.setCurrentCamera(this.camera),this.camera.position.set(s.x,s.y+this.eyeHeight,s.z),this.camera.rotation.set(i.x,i.y,i.z),n&&(this.moveSpeed=n),this.ssp.signals.cameraChange.dispatch(this.camera.position.clone()),this.viewport.postRender.set("FirstPersonControls",this.update.bind(this)),this.ssp.signals.mouseDown.add(this.onMouseDown),this.ssp.signals.mouseUp.add(this.onMouseUp),this.ssp.signals.mouseMove.add(this.onMouseMove),this.ssp.signals.keyDown.add(this.onKeyDown),this.ssp.signals.keyUp.add(this.onKeyUp);const y=this.ssp.viewport.container;y.addEventListener("touchstart",this.onTouchStart),y.addEventListener("touchmove",this.onTouchMove),y.addEventListener("touchend",this.onTouchEnd),this.ssp.signals.objectAdded.add(this.sceneObjectsChanged),this.ssp.signals.objectRemoved.add(this.sceneObjectsChanged)}stop(){t&&this.ssp.setCameraViewpoint(t),this.viewport.controls.currentControls.enabled=!0,this.enabled=!1,this.viewport.cameraManager.setCurrentCamera(this.viewport.cameraManager.getMainCamera()),this.viewport.postRender.delete("FirstPersonControls"),this.ssp.signals.mouseDown.remove(this.onMouseDown),this.ssp.signals.mouseUp.remove(this.onMouseUp),this.ssp.signals.mouseMove.remove(this.onMouseMove),this.ssp.signals.keyDown.remove(this.onKeyDown),this.ssp.signals.keyUp.remove(this.onKeyUp);const e=this.ssp.viewport.container;e.removeEventListener("touchstart",this.onTouchStart),e.removeEventListener("touchmove",this.onTouchMove),e.removeEventListener("touchend",this.onTouchEnd),this.ssp.signals.objectAdded.remove(this.sceneObjectsChanged),this.ssp.signals.objectRemoved.remove(this.sceneObjectsChanged),this.needUpdate()}needUpdate(){this.hasUpdated&&(this.hasUpdated=!1,e=performance.now(),this.ssp.signals.cameraChange.dispatch(this.camera.position.clone()))}update(){if(!this.enabled)return;const t=performance.now(),s=(t-e)/1e3;e=t;const i=this.ssp.THREE,{Vector3:n}=i,a=new i.Vector3,{gravitySpeed:o,moveSpeed:h,state:c,camera:r,eyeHeight:l}=this,{position:d,quaternion:m}=r;let u=0,p=!1;c.moveForward&&(a.z-=h),c.moveBackward&&(a.z+=h),c.moveLeft&&(a.x-=h),c.moveRight&&(a.x+=h),c.moveUp&&(u+=h),c.moveDown&&(u-=h),a.multiplyScalar(s);const v=new i.Euler(0,0,0,"YXZ");v.setFromQuaternion(m);const y=this.movement;if(c.canRotate&&!y.equals(new i.Vector2)){v.x-=.003*this.movement.y,v.y-=.003*this.movement.x;const{max:e,min:t}=this.rotationAngle;v.x=Math.min(e,Math.max(v.x,t)),r.quaternion.setFromEuler(v),p=!0}const g=this.jumpOffset+u*s;if(0!==v.y&&!a.equals(new n)){const e=new i.Quaternion;e.setFromAxisAngle(new n(0,1,0),v.y),a.applyQuaternion(e)}const b=d.clone();!g&&a.equals(new n)||(a.y+=g,this.onClashCheck(d,a)||b.add(a));let w=b.y;if(this.enableGravity){const e=w;w-=o*s,c.canJump=!1;const t=this.gravityClashCheck(b,w);if(t){const e=t.point.y+l;w<e&&(w=e,c.canJump=!0)}e!==w&&this.clearClashCache()}b.y=w;const f=!d.equals(b);f&&r.position.copy(b),this.jumpOffset=0,(f||p)&&this.ssp.signals.cameraChange.dispatch(this.camera.position.clone()),this.hasUpdated=!0}}}));
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import SoonSpace, { Position, Rotation } from 'soonspacejs';
|
|
2
|
+
import { PerspectiveCamera, Vector3, Vector2 } from 'three';
|
|
3
|
+
export declare type ClashCheckAxis = 'front' | 'back' | 'left' | 'right' | 'up' | 'down';
|
|
4
|
+
export interface StartOptions {
|
|
5
|
+
position: Position;
|
|
6
|
+
rotation?: Rotation;
|
|
7
|
+
moveSpeed?: number;
|
|
8
|
+
eyeHeight?: number;
|
|
9
|
+
kneeHeight?: number;
|
|
10
|
+
jumpHeight?: number;
|
|
11
|
+
enableClash?: boolean;
|
|
12
|
+
enableGravity?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export default class FirstPersonControlsPlugin {
|
|
15
|
+
ssp: SoonSpace;
|
|
16
|
+
camera: PerspectiveCamera;
|
|
17
|
+
viewport: SoonSpace['viewport'];
|
|
18
|
+
enabled: boolean;
|
|
19
|
+
rotationAngle: {
|
|
20
|
+
min: number;
|
|
21
|
+
max: number;
|
|
22
|
+
};
|
|
23
|
+
state: {
|
|
24
|
+
moveForward: boolean;
|
|
25
|
+
moveBackward: boolean;
|
|
26
|
+
moveLeft: boolean;
|
|
27
|
+
moveRight: boolean;
|
|
28
|
+
canJump: boolean;
|
|
29
|
+
canRotate: boolean;
|
|
30
|
+
moveUp: boolean;
|
|
31
|
+
moveDown: boolean;
|
|
32
|
+
};
|
|
33
|
+
moveSpeed: number;
|
|
34
|
+
eyeHeight: number;
|
|
35
|
+
kneeHeight: number;
|
|
36
|
+
jumpHeight: number;
|
|
37
|
+
enableClash: boolean;
|
|
38
|
+
enableGravity: boolean;
|
|
39
|
+
readonly velocity: Vector3;
|
|
40
|
+
readonly vector: Vector3;
|
|
41
|
+
readonly movement: Vector2;
|
|
42
|
+
constructor(ssp: SoonSpace);
|
|
43
|
+
onKeyDown(event: KeyboardEvent): void;
|
|
44
|
+
onKeyUp(event: KeyboardEvent): void;
|
|
45
|
+
onMouseDown(event: MouseEvent): void;
|
|
46
|
+
onMouseUp(event: MouseEvent): void;
|
|
47
|
+
onMouseMove(event: MouseEvent): void;
|
|
48
|
+
onRotate(): void;
|
|
49
|
+
onMoveForward(distance: number): void;
|
|
50
|
+
onMoveRight(distance: number): void;
|
|
51
|
+
onMoveUp(distance: number): void;
|
|
52
|
+
onMoveDown(distance: number): void;
|
|
53
|
+
onClashCheck(clashCheckAxis: ClashCheckAxis): boolean;
|
|
54
|
+
start(options: StartOptions): void;
|
|
55
|
+
stop(): void;
|
|
56
|
+
update(): void;
|
|
57
|
+
}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
let prevTime = performance.now();
|
|
2
|
+
const xAxisRotateWidth = 20;
|
|
3
|
+
let cameraViewpointData;
|
|
4
|
+
class FirstPersonControlsPlugin {
|
|
5
|
+
constructor(ssp) {
|
|
6
|
+
this.ssp = ssp;
|
|
7
|
+
this.viewport = ssp.viewport;
|
|
8
|
+
this.camera = this.viewport.cameraManager.createCamera('firstPersonCamera');
|
|
9
|
+
this.enabled = false;
|
|
10
|
+
this.rotationAngle = {
|
|
11
|
+
min: 0,
|
|
12
|
+
max: Math.PI,
|
|
13
|
+
};
|
|
14
|
+
this.state = {
|
|
15
|
+
moveForward: false,
|
|
16
|
+
moveBackward: false,
|
|
17
|
+
moveLeft: false,
|
|
18
|
+
moveRight: false,
|
|
19
|
+
moveUp: false,
|
|
20
|
+
moveDown: false,
|
|
21
|
+
canJump: false,
|
|
22
|
+
canRotate: false,
|
|
23
|
+
};
|
|
24
|
+
this.moveSpeed = 1;
|
|
25
|
+
this.eyeHeight = 160;
|
|
26
|
+
this.kneeHeight = 50;
|
|
27
|
+
this.jumpHeight = 110;
|
|
28
|
+
this.enableClash = true;
|
|
29
|
+
this.enableGravity = true;
|
|
30
|
+
this.onKeyDown = this.onKeyDown.bind(this);
|
|
31
|
+
this.onKeyUp = this.onKeyUp.bind(this);
|
|
32
|
+
this.onMouseDown = this.onMouseDown.bind(this);
|
|
33
|
+
this.onMouseUp = this.onMouseUp.bind(this);
|
|
34
|
+
this.onMouseMove = this.onMouseMove.bind(this);
|
|
35
|
+
this.velocity = new this.ssp.THREE.Vector3;
|
|
36
|
+
this.vector = new this.ssp.THREE.Vector3;
|
|
37
|
+
this.movement = new this.ssp.THREE.Vector2;
|
|
38
|
+
}
|
|
39
|
+
onKeyDown(event) {
|
|
40
|
+
if (this.enabled === false)
|
|
41
|
+
return;
|
|
42
|
+
switch (event.code) {
|
|
43
|
+
case 'ArrowUp':
|
|
44
|
+
case 'KeyW':
|
|
45
|
+
this.state.moveForward = true;
|
|
46
|
+
break;
|
|
47
|
+
case 'ArrowLeft':
|
|
48
|
+
case 'KeyA':
|
|
49
|
+
this.state.moveLeft = true;
|
|
50
|
+
break;
|
|
51
|
+
case 'ArrowDown':
|
|
52
|
+
case 'KeyS':
|
|
53
|
+
this.state.moveBackward = true;
|
|
54
|
+
break;
|
|
55
|
+
case 'ArrowRight':
|
|
56
|
+
case 'KeyD':
|
|
57
|
+
this.state.moveRight = true;
|
|
58
|
+
break;
|
|
59
|
+
case 'KeyI':
|
|
60
|
+
this.state.canRotate = true;
|
|
61
|
+
this.movement.x = 0;
|
|
62
|
+
this.movement.y = -10;
|
|
63
|
+
break;
|
|
64
|
+
case 'KeyJ':
|
|
65
|
+
this.state.canRotate = true;
|
|
66
|
+
this.movement.x = -10;
|
|
67
|
+
this.movement.y = 0;
|
|
68
|
+
break;
|
|
69
|
+
case 'KeyK':
|
|
70
|
+
this.state.canRotate = true;
|
|
71
|
+
this.movement.x = 0;
|
|
72
|
+
this.movement.y = 10;
|
|
73
|
+
break;
|
|
74
|
+
case 'KeyL':
|
|
75
|
+
this.state.canRotate = true;
|
|
76
|
+
this.movement.x = 10;
|
|
77
|
+
this.movement.y = 0;
|
|
78
|
+
break;
|
|
79
|
+
case 'KeyQ':
|
|
80
|
+
this.state.moveUp = true;
|
|
81
|
+
break;
|
|
82
|
+
case 'KeyE':
|
|
83
|
+
this.state.moveDown = true;
|
|
84
|
+
break;
|
|
85
|
+
case 'Space':
|
|
86
|
+
if (this.state.canJump === true)
|
|
87
|
+
this.velocity.y += this.jumpHeight * 3;
|
|
88
|
+
this.state.canJump = false;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
onKeyUp(event) {
|
|
93
|
+
if (this.enabled === false)
|
|
94
|
+
return;
|
|
95
|
+
switch (event.code) {
|
|
96
|
+
case 'ArrowUp':
|
|
97
|
+
case 'KeyW':
|
|
98
|
+
this.state.moveForward = false;
|
|
99
|
+
break;
|
|
100
|
+
case 'ArrowLeft':
|
|
101
|
+
case 'KeyA':
|
|
102
|
+
this.state.moveLeft = false;
|
|
103
|
+
break;
|
|
104
|
+
case 'ArrowDown':
|
|
105
|
+
case 'KeyS':
|
|
106
|
+
this.state.moveBackward = false;
|
|
107
|
+
break;
|
|
108
|
+
case 'ArrowRight':
|
|
109
|
+
case 'KeyD':
|
|
110
|
+
this.state.moveRight = false;
|
|
111
|
+
break;
|
|
112
|
+
case 'KeyI':
|
|
113
|
+
case 'KeyJ':
|
|
114
|
+
case 'KeyK':
|
|
115
|
+
case 'KeyL':
|
|
116
|
+
this.state.canRotate = false;
|
|
117
|
+
break;
|
|
118
|
+
case 'KeyQ':
|
|
119
|
+
this.state.moveUp = false;
|
|
120
|
+
break;
|
|
121
|
+
case 'KeyE':
|
|
122
|
+
this.state.moveDown = false;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
onMouseDown(event) {
|
|
127
|
+
this.state.canRotate = true;
|
|
128
|
+
}
|
|
129
|
+
onMouseUp(event) {
|
|
130
|
+
this.state.canRotate = false;
|
|
131
|
+
}
|
|
132
|
+
onMouseMove(event) {
|
|
133
|
+
if (this.enabled && this.state.canRotate) {
|
|
134
|
+
const movementY = event.movementY;
|
|
135
|
+
let movementX = event.movementX;
|
|
136
|
+
if (movementX === 0) {
|
|
137
|
+
if (event.clientX < xAxisRotateWidth)
|
|
138
|
+
movementX = -10;
|
|
139
|
+
else if (event.clientX > this.viewport.interactiveContainer.clientWidth - xAxisRotateWidth)
|
|
140
|
+
movementX = 10;
|
|
141
|
+
}
|
|
142
|
+
this.movement.x = movementX;
|
|
143
|
+
this.movement.y = movementY;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
onRotate() {
|
|
147
|
+
const euler = new this.ssp.THREE.Euler(0, 0, 0, 'YXZ');
|
|
148
|
+
euler.setFromQuaternion(this.camera.quaternion);
|
|
149
|
+
euler.x -= this.movement.y * 0.003;
|
|
150
|
+
euler.y -= this.movement.x * 0.003;
|
|
151
|
+
euler.x = Math.max(Math.PI / 2 - this.rotationAngle.max, Math.min(Math.PI / 2 - this.rotationAngle.min, euler.x));
|
|
152
|
+
this.camera.quaternion.setFromEuler(euler);
|
|
153
|
+
}
|
|
154
|
+
onMoveForward(distance) {
|
|
155
|
+
this.vector.setFromMatrixColumn(this.camera.matrix, 0);
|
|
156
|
+
this.vector.crossVectors(this.camera.up, this.vector);
|
|
157
|
+
this.camera.position.addScaledVector(this.vector, distance);
|
|
158
|
+
}
|
|
159
|
+
onMoveRight(distance) {
|
|
160
|
+
this.vector.setFromMatrixColumn(this.camera.matrix, 0);
|
|
161
|
+
this.camera.position.addScaledVector(this.vector, distance);
|
|
162
|
+
}
|
|
163
|
+
onMoveUp(distance) {
|
|
164
|
+
this.vector.setFromMatrixColumn(this.camera.matrix, 0);
|
|
165
|
+
this.camera.position.addScaledVector(new this.ssp.THREE.Vector3(0, 1, 0), distance);
|
|
166
|
+
// this.camera.position.addScaledVector(this.vector, distance)
|
|
167
|
+
}
|
|
168
|
+
onMoveDown(distance) {
|
|
169
|
+
this.vector.setFromMatrixColumn(this.camera.matrix, 0);
|
|
170
|
+
this.camera.position.addScaledVector(this.vector, distance);
|
|
171
|
+
}
|
|
172
|
+
onClashCheck(clashCheckAxis) {
|
|
173
|
+
const initDirection = this.camera.getWorldDirection(new this.ssp.THREE.Vector3);
|
|
174
|
+
const useDirection = new this.ssp.THREE.Vector3;
|
|
175
|
+
if (clashCheckAxis === 'front') {
|
|
176
|
+
useDirection.copy(initDirection.clone());
|
|
177
|
+
}
|
|
178
|
+
else if (clashCheckAxis === 'back') {
|
|
179
|
+
useDirection.copy(initDirection.clone().applyAxisAngle(new this.ssp.THREE.Vector3(0, 1, 0), Math.PI));
|
|
180
|
+
}
|
|
181
|
+
else if (clashCheckAxis === 'left') {
|
|
182
|
+
useDirection.copy(initDirection.clone().applyAxisAngle(new this.ssp.THREE.Vector3(0, 1, 0), Math.PI / 2));
|
|
183
|
+
}
|
|
184
|
+
else if (clashCheckAxis === 'right') {
|
|
185
|
+
useDirection.copy(initDirection.clone().applyAxisAngle(new this.ssp.THREE.Vector3(0, 1, 0), -Math.PI / 2));
|
|
186
|
+
}
|
|
187
|
+
else if (clashCheckAxis === 'up') {
|
|
188
|
+
useDirection.copy(new this.ssp.THREE.Vector3(0, 1, 0));
|
|
189
|
+
}
|
|
190
|
+
else if (clashCheckAxis === 'down') {
|
|
191
|
+
useDirection.copy(new this.ssp.THREE.Vector3(0, -1, 0));
|
|
192
|
+
}
|
|
193
|
+
const eyePosition = this.camera.position.clone();
|
|
194
|
+
const eyeRaycaster = new this.ssp.THREE.Raycaster(eyePosition, useDirection, 0, this.eyeHeight / 3);
|
|
195
|
+
eyeRaycaster.camera = this.camera;
|
|
196
|
+
const eyeIntersections = eyeRaycaster.intersectObjects(this.viewport.scener.intersectsList.meshOfModelList);
|
|
197
|
+
const kneePosition = eyePosition.clone().setY(eyePosition.y - this.eyeHeight + this.kneeHeight);
|
|
198
|
+
const kneeRaycaster = new this.ssp.THREE.Raycaster(kneePosition, useDirection, 0, this.eyeHeight / 3);
|
|
199
|
+
kneeRaycaster.camera = this.camera;
|
|
200
|
+
const kneeIntersections = kneeRaycaster.intersectObjects(this.viewport.scener.intersectsList.meshOfModelList);
|
|
201
|
+
if (eyeIntersections.length === 0 && kneeIntersections.length === 0)
|
|
202
|
+
return false;
|
|
203
|
+
else
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
start(options) {
|
|
207
|
+
const { position, rotation = { x: 0, y: 0, z: 0, }, moveSpeed, eyeHeight, kneeHeight, jumpHeight, enableClash, enableGravity, } = options;
|
|
208
|
+
cameraViewpointData = this.ssp.getCameraViewpoint();
|
|
209
|
+
this.viewport.controls.enabled = false;
|
|
210
|
+
this.enabled = true;
|
|
211
|
+
if (eyeHeight)
|
|
212
|
+
this.eyeHeight = eyeHeight;
|
|
213
|
+
if (kneeHeight)
|
|
214
|
+
this.kneeHeight = kneeHeight;
|
|
215
|
+
if (jumpHeight)
|
|
216
|
+
this.jumpHeight = jumpHeight;
|
|
217
|
+
this.enableClash = enableClash !== null && enableClash !== void 0 ? enableClash : true;
|
|
218
|
+
this.enableGravity = enableGravity !== null && enableGravity !== void 0 ? enableGravity : true;
|
|
219
|
+
this.viewport.cameraManager.setCurrentCamera(this.camera);
|
|
220
|
+
this.camera.position.set(position.x, position.y + this.eyeHeight, position.z);
|
|
221
|
+
this.camera.rotation.set(rotation.x, rotation.y, rotation.z);
|
|
222
|
+
if (moveSpeed)
|
|
223
|
+
this.moveSpeed = moveSpeed;
|
|
224
|
+
this.ssp.signals.cameraChange.dispatch(this.camera.position.clone());
|
|
225
|
+
this.viewport.postRender.set('FirstPersonControls', this.update.bind(this));
|
|
226
|
+
this.ssp.signals.mouseDown.add(this.onMouseDown);
|
|
227
|
+
this.ssp.signals.mouseUp.add(this.onMouseUp);
|
|
228
|
+
this.ssp.signals.mouseMove.add(this.onMouseMove);
|
|
229
|
+
this.ssp.signals.keyDown.add(this.onKeyDown);
|
|
230
|
+
this.ssp.signals.keyUp.add(this.onKeyUp);
|
|
231
|
+
}
|
|
232
|
+
stop() {
|
|
233
|
+
cameraViewpointData && this.ssp.setCameraViewpoint(cameraViewpointData);
|
|
234
|
+
this.viewport.controls.enabled = true;
|
|
235
|
+
this.enabled = false;
|
|
236
|
+
this.viewport.cameraManager.setCurrentCamera(this.viewport.cameraManager.getMainCamera());
|
|
237
|
+
this.viewport.postRender.delete('FirstPersonControls');
|
|
238
|
+
this.ssp.signals.mouseDown.remove(this.onMouseDown);
|
|
239
|
+
this.ssp.signals.mouseUp.remove(this.onMouseUp);
|
|
240
|
+
this.ssp.signals.mouseMove.remove(this.onMouseMove);
|
|
241
|
+
this.ssp.signals.keyDown.remove(this.onKeyDown);
|
|
242
|
+
this.ssp.signals.keyUp.remove(this.onKeyUp);
|
|
243
|
+
this.ssp.signals.cameraChange.dispatch(this.camera.position.clone());
|
|
244
|
+
}
|
|
245
|
+
update() {
|
|
246
|
+
const time = performance.now();
|
|
247
|
+
if (this.enabled === true) {
|
|
248
|
+
const gravityRaycaster = new this.ssp.THREE.Raycaster(this.camera.position, new this.ssp.THREE.Vector3(0, -1, 0));
|
|
249
|
+
gravityRaycaster.camera = this.camera;
|
|
250
|
+
const gravityIntersections = gravityRaycaster.intersectObjects(this.viewport.scener.intersectsList.getAll());
|
|
251
|
+
const delta = (time - prevTime) / 1000;
|
|
252
|
+
this.velocity.x = 0;
|
|
253
|
+
this.velocity.z = 0;
|
|
254
|
+
if (this.enableGravity) {
|
|
255
|
+
this.velocity.y -= delta * 1000;
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
this.velocity.y = 0;
|
|
259
|
+
}
|
|
260
|
+
if (this.state.moveForward) {
|
|
261
|
+
if (this.enableClash && this.onClashCheck('front'))
|
|
262
|
+
this.velocity.z = 0;
|
|
263
|
+
else
|
|
264
|
+
this.velocity.z -= 400.0 * delta;
|
|
265
|
+
}
|
|
266
|
+
if (this.state.moveBackward) {
|
|
267
|
+
if (this.enableClash && this.onClashCheck('back'))
|
|
268
|
+
this.velocity.z = 0;
|
|
269
|
+
else
|
|
270
|
+
this.velocity.z += 400.0 * delta;
|
|
271
|
+
}
|
|
272
|
+
if (this.state.moveLeft) {
|
|
273
|
+
if (this.enableClash && this.onClashCheck('left'))
|
|
274
|
+
this.velocity.x = 0;
|
|
275
|
+
else
|
|
276
|
+
this.velocity.x += 400.0 * delta;
|
|
277
|
+
}
|
|
278
|
+
if (this.state.moveRight) {
|
|
279
|
+
if (this.enableClash && this.onClashCheck('right'))
|
|
280
|
+
this.velocity.x = 0;
|
|
281
|
+
else
|
|
282
|
+
this.velocity.x -= 400.0 * delta;
|
|
283
|
+
}
|
|
284
|
+
if (this.state.moveUp) {
|
|
285
|
+
if (this.enableClash && this.onClashCheck('up'))
|
|
286
|
+
this.velocity.y = 0;
|
|
287
|
+
else
|
|
288
|
+
this.velocity.y += 400.0 * delta;
|
|
289
|
+
}
|
|
290
|
+
if (this.state.moveDown) {
|
|
291
|
+
if (this.enableClash && this.onClashCheck('down'))
|
|
292
|
+
this.velocity.y = 0;
|
|
293
|
+
else
|
|
294
|
+
this.velocity.y -= 400.0 * delta;
|
|
295
|
+
}
|
|
296
|
+
this.onMoveRight(-this.velocity.x * delta * 10 * this.moveSpeed);
|
|
297
|
+
this.onMoveForward(-this.velocity.z * delta * 10 * this.moveSpeed);
|
|
298
|
+
//不需要重力检测时,才会有抬起下降功能
|
|
299
|
+
if (!this.enableGravity)
|
|
300
|
+
this.onMoveUp(-this.velocity.y * delta * 10 * this.moveSpeed);
|
|
301
|
+
else {
|
|
302
|
+
this.camera.position.y += (this.velocity.y * delta);
|
|
303
|
+
}
|
|
304
|
+
if (gravityIntersections.length > 0) {
|
|
305
|
+
const minheight = gravityIntersections[0].point.y + this.eyeHeight;
|
|
306
|
+
if (this.camera.position.y < minheight) {
|
|
307
|
+
this.camera.position.y = minheight;
|
|
308
|
+
this.velocity.y = 0;
|
|
309
|
+
this.state.canJump = true;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
if (this.enableGravity) {
|
|
314
|
+
this.velocity.y -= 100 * delta,
|
|
315
|
+
this.camera.position.y += (this.velocity.y * delta),
|
|
316
|
+
this.state.canJump = false;
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
this.velocity.y = 0;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if (this.state.canRotate)
|
|
323
|
+
this.onRotate();
|
|
324
|
+
}
|
|
325
|
+
prevTime = time;
|
|
326
|
+
this.ssp.signals.cameraChange.dispatch(this.camera.position.clone());
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export { FirstPersonControlsPlugin as default };
|
|
331
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/index.ts"],"sourcesContent":["import SoonSpace, { Position, Rotation, CameraViewpointData, } from 'soonspacejs'\nimport { PerspectiveCamera, Vector3, Vector2, } from 'three'\n\nlet prevTime = performance.now()\nconst xAxisRotateWidth = 20\n\nlet cameraViewpointData: CameraViewpointData | undefined\n\nexport type ClashCheckAxis = 'front' | 'back' | 'left' | 'right' | 'up' | 'down' \n\nexport interface StartOptions {\n position: Position;\n rotation?: Rotation;\n moveSpeed?: number;\n eyeHeight?: number;\n kneeHeight?: number;\n jumpHeight?: number;\n enableClash?: boolean;\n enableGravity?: boolean;\n}\n\nexport default class FirstPersonControlsPlugin {\n\n ssp: SoonSpace\n camera: PerspectiveCamera\n viewport: SoonSpace['viewport']\n enabled: boolean\n\n rotationAngle: {\n min: number;\n max: number;\n }\n state: {\n moveForward: boolean;\n moveBackward: boolean;\n moveLeft: boolean;\n moveRight: boolean;\n canJump: boolean;\n canRotate: boolean;\n moveUp: boolean;\n moveDown: boolean;\n }\n\n moveSpeed: number\n\n eyeHeight: number\n kneeHeight: number\n jumpHeight: number\n\n enableClash: boolean\n enableGravity: boolean\n\n readonly velocity: Vector3\n readonly vector: Vector3\n readonly movement: Vector2\n\n constructor ( ssp: SoonSpace ) {\n\n this.ssp = ssp\n\n this.viewport = ssp.viewport\n this.camera = this.viewport.cameraManager.createCamera( 'firstPersonCamera' )\n\n this.enabled = false\n\n this.rotationAngle = {\n min: 0,\n max: Math.PI,\n }\n\n this.state = {\n moveForward: false,\n moveBackward: false,\n moveLeft: false,\n moveRight: false,\n moveUp: false,\n moveDown: false,\n canJump: false,\n canRotate: false,\n }\n\n this.moveSpeed = 1\n\n this.eyeHeight = 160\n this.kneeHeight = 50\n this.jumpHeight = 110\n\n this.enableClash = true\n this.enableGravity = true\n\n this.onKeyDown = this.onKeyDown.bind( this )\n this.onKeyUp = this.onKeyUp.bind( this )\n this.onMouseDown = this.onMouseDown.bind( this )\n this.onMouseUp = this.onMouseUp.bind( this )\n this.onMouseMove = this.onMouseMove.bind( this )\n\n this.velocity = new this.ssp.THREE.Vector3\n this.vector = new this.ssp.THREE.Vector3\n this.movement = new this.ssp.THREE.Vector2\n\n }\n\n onKeyDown ( event: KeyboardEvent ): void {\n\n if ( this.enabled === false ) return\n\n switch ( event.code ) {\n\n case 'ArrowUp':\n case 'KeyW':\n this.state.moveForward = true\n break\n\n case 'ArrowLeft':\n case 'KeyA':\n this.state.moveLeft = true\n break\n\n case 'ArrowDown':\n case 'KeyS':\n this.state.moveBackward = true\n break\n\n case 'ArrowRight':\n case 'KeyD':\n this.state.moveRight = true\n break\n\n case 'KeyI':\n this.state.canRotate = true\n this.movement.x = 0\n this.movement.y = -10\n break\n\n case 'KeyJ':\n this.state.canRotate = true\n this.movement.x = -10\n this.movement.y = 0\n break\n\n case 'KeyK':\n this.state.canRotate = true\n this.movement.x = 0\n this.movement.y = 10\n break\n\n case 'KeyL':\n this.state.canRotate = true\n this.movement.x = 10\n this.movement.y = 0\n break\n\n case 'KeyQ':\n this.state.moveUp = true\n break\n case 'KeyE':\n this.state.moveDown = true\n break\n\n case 'Space':\n if ( this.state.canJump === true ) this.velocity.y += this.jumpHeight * 3\n this.state.canJump = false\n break\n\n }\n\n }\n\n onKeyUp ( event: KeyboardEvent ): void {\n\n if ( this.enabled === false ) return\n\n switch ( event.code ) {\n \n case 'ArrowUp':\n case 'KeyW':\n this.state.moveForward = false\n break\n\n case 'ArrowLeft':\n case 'KeyA':\n this.state.moveLeft = false\n break\n\n case 'ArrowDown':\n case 'KeyS':\n this.state.moveBackward = false\n break\n\n case 'ArrowRight':\n case 'KeyD':\n this.state.moveRight = false\n break\n\n case 'KeyI':\n case 'KeyJ':\n case 'KeyK':\n case 'KeyL':\n this.state.canRotate = false\n break\n case 'KeyQ':\n this.state.moveUp = false\n break\n case 'KeyE':\n this.state.moveDown = false\n break\n \n }\n\n }\n\n onMouseDown ( event: MouseEvent ): void {\n\n this.state.canRotate = true\n \n }\n\n onMouseUp ( event: MouseEvent ): void {\n\n this.state.canRotate = false\n \n }\n\n onMouseMove ( event: MouseEvent ): void {\n\n if ( this.enabled && this.state.canRotate ) {\n\n const movementY = event.movementY\n let movementX = event.movementX\n\n if ( movementX === 0 ) {\n\n if ( event.clientX < xAxisRotateWidth ) movementX = -10\n else if ( event.clientX > this.viewport.interactiveContainer.clientWidth - xAxisRotateWidth ) movementX = 10\n \n }\n\n this.movement.x = movementX\n this.movement.y = movementY\n\n }\n\n }\n\n onRotate () {\n\n const euler = new this.ssp.THREE.Euler( 0, 0, 0, 'YXZ' )\n\n euler.setFromQuaternion( this.camera.quaternion )\n\n euler.x -= this.movement.y * 0.003\n euler.y -= this.movement.x * 0.003\n\n euler.x = Math.max( Math.PI / 2 - this.rotationAngle.max, Math.min( Math.PI / 2 - this.rotationAngle.min, euler.x ) )\n\n this.camera.quaternion.setFromEuler( euler )\n\n }\n\n onMoveForward ( distance: number ): void {\n\n this.vector.setFromMatrixColumn( this.camera.matrix, 0 )\n\n this.vector.crossVectors( this.camera.up, this.vector )\n\n this.camera.position.addScaledVector( this.vector, distance ) \n \n }\n\n onMoveRight ( distance: number ): void {\n\n this.vector.setFromMatrixColumn( this.camera.matrix, 0 )\n\n this.camera.position.addScaledVector( this.vector, distance )\n\n }\n\n onMoveUp ( distance: number ): void {\n\n this.vector.setFromMatrixColumn( this.camera.matrix, 0 )\n\n this.camera.position.addScaledVector( new this.ssp.THREE.Vector3( 0, 1, 0 ), distance )\n // this.camera.position.addScaledVector(this.vector, distance)\n \n }\n\n onMoveDown ( distance: number ): void {\n\n this.vector.setFromMatrixColumn( this.camera.matrix, 0 )\n\n this.camera.position.addScaledVector( this.vector, distance )\n\n }\n\n onClashCheck ( clashCheckAxis: ClashCheckAxis ): boolean {\n\n const initDirection = this.camera.getWorldDirection( new this.ssp.THREE.Vector3 )\n const useDirection = new this.ssp.THREE.Vector3\n\n if ( clashCheckAxis === 'front' ) {\n\n useDirection.copy( initDirection.clone() )\n \n } else if ( clashCheckAxis === 'back' ) {\n\n useDirection.copy( initDirection.clone().applyAxisAngle( new this.ssp.THREE.Vector3( 0, 1, 0 ), Math.PI ) )\n \n } else if ( clashCheckAxis === 'left' ) {\n\n useDirection.copy( initDirection.clone().applyAxisAngle( new this.ssp.THREE.Vector3( 0, 1, 0 ), Math.PI / 2 ) )\n \n } else if ( clashCheckAxis === 'right' ) {\n\n useDirection.copy( initDirection.clone().applyAxisAngle( new this.ssp.THREE.Vector3( 0, 1, 0 ), -Math.PI / 2 ) )\n \n } else if ( clashCheckAxis === 'up' ) {\n\n useDirection.copy( new this.ssp.THREE.Vector3( 0, 1, 0 ) )\n \n } else if ( clashCheckAxis === 'down' ) {\n\n useDirection.copy( new this.ssp.THREE.Vector3( 0, -1, 0 ) )\n \n }\n\n const eyePosition = this.camera.position.clone()\n const eyeRaycaster = new this.ssp.THREE.Raycaster( eyePosition, useDirection, 0, this.eyeHeight / 3 )\n\n eyeRaycaster.camera = this.camera\n\n const eyeIntersections = eyeRaycaster.intersectObjects( this.viewport.scener.intersectsList.meshOfModelList )\n\n const kneePosition = eyePosition.clone().setY( eyePosition.y - this.eyeHeight + this.kneeHeight )\n const kneeRaycaster = new this.ssp.THREE.Raycaster( kneePosition, useDirection, 0, this.eyeHeight / 3 )\n\n kneeRaycaster.camera = this.camera\n\n const kneeIntersections = kneeRaycaster.intersectObjects( this.viewport.scener.intersectsList.meshOfModelList )\n\n if ( eyeIntersections.length === 0 && kneeIntersections.length === 0 ) return false\n else return true\n \n }\n\n start ( options: StartOptions ): void {\n\n const {\n position,\n rotation = { x: 0, y: 0, z: 0, },\n moveSpeed,\n eyeHeight,\n kneeHeight,\n jumpHeight,\n enableClash,\n enableGravity,\n } = options\n\n cameraViewpointData = this.ssp.getCameraViewpoint()\n\n this.viewport.controls.enabled = false\n this.enabled = true\n\n if ( eyeHeight ) this.eyeHeight = eyeHeight\n if ( kneeHeight ) this.kneeHeight = kneeHeight\n if ( jumpHeight ) this.jumpHeight = jumpHeight\n this.enableClash = enableClash ?? true\n this.enableGravity = enableGravity ?? true\n\n this.viewport.cameraManager.setCurrentCamera( this.camera )\n\n this.camera.position.set( position.x, position.y + this.eyeHeight, position.z )\n this.camera.rotation.set( rotation.x, rotation.y, rotation.z )\n\n if ( moveSpeed ) this.moveSpeed = moveSpeed\n\n this.ssp.signals.cameraChange.dispatch( this.camera.position.clone() )\n\n this.viewport.postRender.set( 'FirstPersonControls', this.update.bind( this ) )\n\n this.ssp.signals.mouseDown.add( this.onMouseDown )\n this.ssp.signals.mouseUp.add( this.onMouseUp )\n this.ssp.signals.mouseMove.add( this.onMouseMove )\n this.ssp.signals.keyDown.add( this.onKeyDown )\n this.ssp.signals.keyUp.add( this.onKeyUp )\n \n }\n\n stop (): void {\n\n cameraViewpointData && this.ssp.setCameraViewpoint( cameraViewpointData )\n this.viewport.controls.enabled = true\n this.enabled = false\n\n this.viewport.cameraManager.setCurrentCamera( this.viewport.cameraManager.getMainCamera() )\n\n this.viewport.postRender.delete( 'FirstPersonControls' )\n\n this.ssp.signals.mouseDown.remove( this.onMouseDown )\n this.ssp.signals.mouseUp.remove( this.onMouseUp )\n this.ssp.signals.mouseMove.remove( this.onMouseMove )\n this.ssp.signals.keyDown.remove( this.onKeyDown )\n this.ssp.signals.keyUp.remove( this.onKeyUp )\n\n this.ssp.signals.cameraChange.dispatch( this.camera.position.clone() )\n \n }\n\n update (): void {\n\n const time = performance.now()\n\n if ( this.enabled === true ) {\n\n const gravityRaycaster = new this.ssp.THREE.Raycaster( this.camera.position, new this.ssp.THREE.Vector3( 0, -1, 0 ) )\n\n gravityRaycaster.camera = this.camera\n \n const gravityIntersections = gravityRaycaster.intersectObjects( this.viewport.scener.intersectsList.getAll() )\n\n const delta = ( time - prevTime ) / 1000\n\n this.velocity.x = 0\n this.velocity.z = 0\n if ( this.enableGravity ) {\n\n this.velocity.y -= delta * 1000\n \n }\n else {\n\n this.velocity.y = 0\n \n }\n if ( this.state.moveForward ) {\n\n if ( this.enableClash && this.onClashCheck( 'front' ) ) this.velocity.z = 0\n else this.velocity.z -= 400.0 * delta\n \n }\n\n if ( this.state.moveBackward ) {\n\n if ( this.enableClash && this.onClashCheck( 'back' ) ) this.velocity.z = 0\n else this.velocity.z += 400.0 * delta\n \n }\n\n if ( this.state.moveLeft ) {\n\n if ( this.enableClash && this.onClashCheck( 'left' ) ) this.velocity.x = 0\n else this.velocity.x += 400.0 * delta\n \n }\n\n if ( this.state.moveRight ) {\n\n if ( this.enableClash && this.onClashCheck( 'right' ) ) this.velocity.x = 0\n else this.velocity.x -= 400.0 * delta\n \n }\n\n if ( this.state.moveUp ) {\n\n if ( this.enableClash && this.onClashCheck( 'up' ) ) this.velocity.y = 0\n else this.velocity.y += 400.0 * delta\n \n }\n\n if ( this.state.moveDown ) {\n\n if ( this.enableClash && this.onClashCheck( 'down' ) ) this.velocity.y = 0\n else this.velocity.y -= 400.0 * delta\n \n }\n\n this.onMoveRight( -this.velocity.x * delta * 10 * this.moveSpeed )\n this.onMoveForward( -this.velocity.z * delta * 10 * this.moveSpeed )\n //不需要重力检测时,才会有抬起下降功能\n if ( !this.enableGravity ) this.onMoveUp( -this.velocity.y * delta * 10 * this.moveSpeed )\n else {\n\n this.camera.position.y += ( this.velocity.y * delta )\n \n }\n\n if ( gravityIntersections.length > 0 ) {\n\n const minheight = gravityIntersections[ 0 ].point.y + this.eyeHeight\n\n if ( this.camera.position.y < minheight ) {\n\n this.camera.position.y = minheight\n this.velocity.y = 0\n this.state.canJump = true\n \n }\n \n } else {\n\n if ( this.enableGravity ) {\n\n this.velocity.y -= 100 * delta,\n this.camera.position.y += ( this.velocity.y * delta ),\n this.state.canJump = false\n \n }\n else {\n\n this.velocity.y = 0\n \n }\n\n }\n\n if ( this.state.canRotate ) this.onRotate()\n\n }\n\n prevTime = time\n\n this.ssp.signals.cameraChange.dispatch( this.camera.position.clone() )\n\n }\n\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8">
|
|
6
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
8
|
+
<title>Document</title>
|
|
9
|
+
<style>
|
|
10
|
+
* {
|
|
11
|
+
margin: 0;
|
|
12
|
+
}
|
|
13
|
+
</style>
|
|
14
|
+
</head>
|
|
15
|
+
|
|
16
|
+
<body>
|
|
17
|
+
<div id="view" style="width: 100vw; height: 100vh;"></div>
|
|
18
|
+
<script type="module">
|
|
19
|
+
|
|
20
|
+
import SoonSpace from '../../../soonspacejs/dist/index.esm.js'
|
|
21
|
+
import FirstPersonControlsPlugin from '../dist-ori/index.esm.js'
|
|
22
|
+
|
|
23
|
+
const ssp = window.ssp = new SoonSpace({
|
|
24
|
+
el: '#view',
|
|
25
|
+
options: {
|
|
26
|
+
showInfo: true,
|
|
27
|
+
showGrid: false
|
|
28
|
+
},
|
|
29
|
+
events: {
|
|
30
|
+
selectPosition(position) {
|
|
31
|
+
console.log(position)
|
|
32
|
+
},
|
|
33
|
+
modelClick(p) {
|
|
34
|
+
console.log(p)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const ground = ssp.addGroundHelper({
|
|
40
|
+
id: 'ground',
|
|
41
|
+
imgUrl: '../../../../__test__/img/ground/001.jpg',
|
|
42
|
+
width: 10000,
|
|
43
|
+
height: 10000,
|
|
44
|
+
opacity: 1
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
console.log(ground)
|
|
48
|
+
|
|
49
|
+
const poi = ssp.createPoi({
|
|
50
|
+
url: '../../../../__test__/img/poi_001.png',
|
|
51
|
+
id: 'test_poi_001',
|
|
52
|
+
name: 'test_poi_001',
|
|
53
|
+
position: {
|
|
54
|
+
x: 100,
|
|
55
|
+
y: 500,
|
|
56
|
+
z: 0
|
|
57
|
+
},
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
ssp.loadModel({
|
|
61
|
+
id: 'room',
|
|
62
|
+
// url: '../../../../__test__/model/sbk/changjing02/changjing02_1F_0.sbm',
|
|
63
|
+
url: '../../../../__test__/model/sbmx/区间疏散平台0610-out/区间疏散平台0610.sbmx',
|
|
64
|
+
position: {
|
|
65
|
+
x: 100,
|
|
66
|
+
y: 120,
|
|
67
|
+
z: 100
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
ssp.loadModel({
|
|
71
|
+
id: 'room',
|
|
72
|
+
url: '../../../../__test__/model/sbk/changjing02/changjing02_1F_0.sbm',
|
|
73
|
+
position: {
|
|
74
|
+
x: 100,
|
|
75
|
+
y: 120,
|
|
76
|
+
z: 100
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
.then(sbm => {
|
|
80
|
+
return ssp.flyToObj(sbm, "leftFrontTop", { padding: 100 })
|
|
81
|
+
})
|
|
82
|
+
.then(sbm => {
|
|
83
|
+
const firstPersonControls = ssp.registerPlugin(FirstPersonControlsPlugin, 'firstPersonControls')
|
|
84
|
+
console.log(firstPersonControls)
|
|
85
|
+
|
|
86
|
+
firstPersonControls.start({
|
|
87
|
+
position: { x: 260, y: 50, z: 100 },
|
|
88
|
+
rotation: { x: 0, y: 0, z: 0 },
|
|
89
|
+
moveSpeed: 10.0,
|
|
90
|
+
enableClash: true,
|
|
91
|
+
enableGravity: true
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
// function animation() {
|
|
97
|
+
// requestAnimationFrame(animation)
|
|
98
|
+
|
|
99
|
+
// let str = "sssssssdashjdgwaygdklasujgdsadiu";
|
|
100
|
+
// for (let i = 0; i < 300000; i++) {
|
|
101
|
+
// JSON.parse(JSON.stringify(str));
|
|
102
|
+
// }
|
|
103
|
+
// }
|
|
104
|
+
|
|
105
|
+
// animation()
|
|
106
|
+
</script>
|
|
107
|
+
</body>
|
|
108
|
+
|
|
109
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@soonspacejs/plugin-first-person-controls",
|
|
3
3
|
"pluginName": "FirstPersonControlsPlugin",
|
|
4
|
-
"version": "2.5.
|
|
4
|
+
"version": "2.5.10",
|
|
5
5
|
"description": "FirstPersonControls plugin for SoonSpace.js",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.esm.js",
|
|
@@ -13,5 +13,5 @@
|
|
|
13
13
|
],
|
|
14
14
|
"author": "xuek",
|
|
15
15
|
"license": "UNLICENSED",
|
|
16
|
-
"gitHead": "
|
|
16
|
+
"gitHead": "41a0a0aaba7262979f8a232ad0098e01c7c5c90a"
|
|
17
17
|
}
|