Skip to content

Commit f596b0b

Browse files
committed
Custom Ray Casters further implemented
Added a screen space ray caster from camera to enable clickable, hoverable, and promo collision detection. -Currently broken in Public/Source, awaiting updates to pxlCamera.mainColliderCheck() --Ground Collider checks assume for -Y gravity for now Next push should be a gridded hashmap ground, wall, wall_top colliders and interactable colliders
1 parent 42a5af5 commit f596b0b

File tree

8 files changed

+481
-166
lines changed

8 files changed

+481
-166
lines changed

Source/js/pxlNav/Environment.js

Lines changed: 58 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import {
3434
LinearSRGBColorSpace
3535
} from "../libs/three/three.module.min.js";
3636

37-
import { ANTI_ALIASING, VERBOSE_LEVEL } from "./core/Enums.js";
37+
import { ANTI_ALIASING, VERBOSE_LEVEL, COLLIDER_TYPE } from "./core/Enums.js";
3838
import { pxlOptions } from "./core/Options.js";
3939

4040
import { EffectComposer } from '../libs/three/EffectComposer.js';
@@ -108,6 +108,7 @@ export class Environment{
108108
this.pxlUtils=null;
109109
this.pxlTimer=null;
110110
this.pxlAnim=null;
111+
this.pxlColliders=null;
111112
this.pxlAutoCam=null;
112113
this.pxlAudio=null;
113114
this.pxlFile=null;
@@ -271,6 +272,7 @@ export class Environment{
271272
this.pxlUtils=pxlNav.pxlUtils;
272273
this.pxlTimer=pxlNav.pxlTimer;
273274
this.pxlAnim=pxlNav.pxlAnim;
275+
this.pxlColliders=pxlNav.pxlColliders;
274276
this.pxlAutoCam=pxlNav.pxlAutoCam;
275277
this.pxlAudio=pxlNav.pxlAudio;
276278
this.pxlFile=pxlNav.pxlFile;
@@ -725,54 +727,39 @@ export class Environment{
725727
// In-Scene clickables
726728
clickUserDetect(){
727729

728-
if( this.roomSceneList[this.currentRoom].castRay ){
729-
this.roomSceneList[this.currentRoom].castRay( true, this.pxlDevice.touchMouseData.button )
730-
}
731-
732-
if( this.pxlDevice.mobile ){
733-
return;
734-
}
735-
736-
let objHit=null;
737-
let mouseScreenSpace=new Vector2( this.pxlDevice.mouseX/this.pxlDevice.sW*2-1, -this.pxlDevice.mouseY/this.pxlDevice.sH*2+1 );
738-
this.pxlCamera.objRaycast.setFromCamera(mouseScreenSpace, this.pxlCamera.camera );
739-
var rayHits=[];
740-
//if(this.camScreenData.screenClickable.length>0) rayHits=this.pxlCamera.objRaycast.intersectObjects(this.camScreenData.screenClickable);//this.scene.children);
741-
if(this.objectClickable.length>0) rayHits=this.pxlCamera.objRaycast.intersectObjects(this.objectClickable);//this.scene.children);
742-
if(rayHits.length > 0){
743-
let closestHit=99999;
744-
for(var x=0; x<rayHits.length;++x){
745-
var obj=rayHits[x];//.object;
746-
let curDist=obj.distance;
747-
if(curDist<closestHit){
748-
objHit=obj.object;
749-
closestHit=Math.min(closestHit, curDist);
750-
}
751-
}
730+
// Current Room Obj
731+
let curRoomObj = this.roomSceneList[ this.currentRoom ];
732+
733+
// Cast mouse or touch position to NDC
734+
let mouseScreenSpace = this.pxlUtils.screenToNDC( this.pxlDevice.mouseX, this.pxlDevice.mouseY, this.pxlDevice.sW, this.pxlDevice.sH );
735+
736+
// Get clickable objects under mouse
737+
let rayHits={};
738+
if( curRoomObj.hasColliderType( COLLIDER_TYPE.CLICKABLE ) ){
739+
let curObjList = curRoomObj.getColliders( COLLIDER_TYPE.CLICKABLE );
740+
rayHits = this.pxlColliders.castInteractRay( this.currentRoom, curObjList, this.pxlCamera.camera, mouseScreenSpace );
752741
}
753-
if(objHit){
742+
743+
// Get nearest object hit,
744+
// rayHits.order is an array of objects hit, in order of distance
745+
if( rayHits.hasOwnProperty("order") && rayHits.order.length > 0 ){
746+
let objHit = rayHits.order[0];
754747
this.clickableActions(objHit.name);
748+
return;
755749
}
756-
757-
758-
let promoHit=null;
759-
if(this.promoClickable.length>0) rayHits=this.pxlCamera.objRaycast.intersectObjects(this.promoClickable);//this.scene.children);
760-
if(rayHits.length > 0){
761-
let closestHit=99999;
762-
for(var x=0; x<rayHits.length;++x){
763-
var obj=rayHits[x];//.object;
764-
let curDist=obj.distance;
765-
if(curDist<closestHit){
766-
promoHit=obj.object;
767-
closestHit=Math.min(closestHit, curDist);
768-
}
769-
}
770-
}
771-
if(promoHit){
772-
this.promoActions(promoHit);
750+
751+
// -- -- --
752+
753+
// If no clickable object hit, check for promo clickables
754+
rayHits = {};
755+
rayHits = this.pxlColliders.castInteractRay( this.currentRoom, this.promoClickable, this.pxlCamera.camera, mouseScreenSpace );
756+
757+
if(rayHits.hasOwnProperty("order") && rayHits.order.length > 0){
758+
let promoHit = rayHits.order[0];
759+
this.promoActions( promoHit );
773760
}
774-
775761
}
762+
776763
clickableActions(action=null){
777764
if(action == "CallToAction" && this.clickablePrevActiveObject){
778765
this.pxlGuiDraws.ctaBuildPopup();
@@ -794,28 +781,24 @@ export class Environment{
794781
// Hover over clickable
795782
hoverUserDetect(){
796783

797-
if( this.roomSceneList[this.currentRoom].castRay ){
798-
this.roomSceneList[this.currentRoom].castRay( false, this.pxlDevice.touchMouseData.button )
799-
}
800-
801-
let objHit=null;
802-
let mouseScreenSpace=new Vector2( this.pxlDevice.mouseX/this.pxlDevice.sW*2-1, -this.pxlDevice.mouseY/this.pxlDevice.sH*2+1 );
803-
this.pxlCamera.objRaycast.setFromCamera(mouseScreenSpace, this.pxlCamera.camera );
804-
var rayHits=[];
805-
//if(this.camScreenData.screenClickable.length>0) rayHits=this.pxlCamera.objRaycast.intersectObjects(this.camScreenData.screenClickable);//this.scene.children);
806-
if(this.objectClickable.length>0) rayHits=this.pxlCamera.objRaycast.intersectObjects(this.objectClickable);
807-
if(rayHits.length > 0){
808-
let closestHit=99999;
809-
for(var x=0; x<rayHits.length;++x){
810-
var obj=rayHits[x];//.object;
811-
let curDist=obj.distance;
812-
if(curDist<closestHit){
813-
objHit=obj.object;
814-
closestHit=Math.min(closestHit, curDist);
815-
}
816-
}
784+
// Current Room Obj
785+
let curRoomObj = this.roomSceneList[ this.currentRoom ];
786+
787+
// Cast mouse or touch position to NDC
788+
let mouseScreenSpace = this.pxlUtils.screenToNDC( this.pxlDevice.mouseX, this.pxlDevice.mouseY, this.pxlDevice.sW, this.pxlDevice.sH );
789+
790+
// Get hoverable objects under mouse
791+
let rayHits={};
792+
if( curRoomObj.hasColliderType( COLLIDER_TYPE.CLICKABLE ) || curRoomObj.hasColliderType( COLLIDER_TYPE.HOVERABLE ) ){
793+
// Combine objectClickable with objectHoverable This may change
794+
let curObjList = [ ...curRoomObj.getColliders( COLLIDER_TYPE.CLICKABLE ), ...curRoomObj.getColliders( COLLIDER_TYPE.HOVERABLE ) ];
795+
rayHits = this.pxlColliders.castInteractRay( this.currentRoom, curObjList, this.pxlCamera.camera, mouseScreenSpace );
817796
}
818-
if(objHit){
797+
798+
// Get nearest object hit,
799+
// rayHits.order is an array of objects hit, in order of distance
800+
if( rayHits.hasOwnProperty("order") && rayHits.order.length > 0 ){
801+
let objHit = rayHits.order[0];
819802
this.pxlDevice.setCursor("help");
820803
if(this.objectClickableObjectList[objHit.name]){
821804
if(this.clickablePrevActiveObject==null){
@@ -824,7 +807,7 @@ export class Environment{
824807
this.objectClickableObjectList[objHit.name]['Inactive'].visible=false;
825808
this.objectClickableObjectList[objHit.name]['Hover'].visible=true;
826809
}
827-
return;
810+
return;
828811
}else{
829812
if(this.clickablePrevActiveObject){
830813
this.objectClickableObjectList[this.clickablePrevActiveObject]['Inactive'].visible=true;
@@ -833,22 +816,15 @@ export class Environment{
833816
}
834817
this.pxlDevice.setCursor("grab");
835818
}
836-
837-
838-
let promoHit=null;
839-
if(this.promoClickable.length>0) rayHits=this.pxlCamera.objRaycast.intersectObjects(this.promoClickable);
840-
if(rayHits.length > 0){
841-
let closestHit=99999;
842-
for(var x=0; x<rayHits.length;++x){
843-
var obj=rayHits[x];//.object;
844-
let curDist=obj.distance;
845-
if(curDist<closestHit){
846-
promoHit=obj.object;
847-
closestHit=Math.min(closestHit, curDist);
848-
}
849-
}
850-
}
851-
if(promoHit){
819+
820+
// -- -- --
821+
822+
// If no clickable object hit, check for promo clickables
823+
rayHits = {};
824+
rayHits = this.pxlColliders.castInteractRay( this.currentRoom, this.promoClickable, this.pxlCamera.camera, mouseScreenSpace );
825+
826+
if(rayHits.hasOwnProperty("order") && rayHits.order.length > 0){
827+
let promoHit = rayHits.order[0];
852828
this.pxlDevice.setCursor("alias");
853829
if(this.promoClickableObjectList[promoHit.name]){
854830
if(this.promoPrevActiveObject==null){

Source/js/pxlNav/RoomClass.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,10 @@ class RoomEnvironment{
107107

108108

109109
this.enableRaycast = false;
110-
this.hoverableExists=false;
110+
this.hasHoverables=false;
111111
this.hoverableList=[];
112112
this.hoverableObj=null;
113-
this.clickableExists=false;
113+
this.hasClickables=false;
114114
this.clickableList=[];
115115
this.clickableObj=null;
116116

@@ -325,16 +325,16 @@ class RoomEnvironment{
325325
if(!this.enableRaycast){
326326
return;
327327
}
328-
if( ( !isClick && !this.hoverableExists ) || ( isClick && !this.clickableExists ) ){
328+
if( ( !isClick && !this.hasHoverables ) || ( isClick && !this.hasClickables ) ){
329329
//console.log("No Cickable / Hoverable Objects Found");
330330
this.mouseRayHits=[];
331331
return;
332332
}
333333

334334
let castableObjects = []
335-
if( !isClick && this.hoverableExists ) {
335+
if( !isClick && this.hasHoverables ) {
336336
castableObjects = this.hoverableList;
337-
}else if( isClick && this.clickableExists ){
337+
}else if( isClick && this.hasClickables ){
338338
castableObjects = this.clickableList;
339339
}
340340

@@ -369,7 +369,7 @@ class RoomEnvironment{
369369
case COLLIDER_TYPE.WALL:
370370
hasCollidersOfType = this.colliderActive;
371371
break;
372-
case COLLIDER_TYPE.TOP:
372+
case COLLIDER_TYPE.WALL_TOP:
373373
hasCollidersOfType = this.antiColliderTopActive;
374374
break;
375375
case COLLIDER_TYPE.CEILING:
@@ -387,6 +387,12 @@ class RoomEnvironment{
387387
case COLLIDER_TYPE.SCRIPTED:
388388
// Not implemented yet
389389
break;
390+
case COLLIDER_TYPE.HOVERABLE:
391+
hasCollidersOfType = this.hasHoverables;
392+
break;
393+
case COLLIDER_TYPE.CLICKABLE:
394+
hasCollidersOfType = this.hasClickables;
395+
break;
390396
}
391397

392398
return hasCollidersOfType;
@@ -404,12 +410,20 @@ class RoomEnvironment{
404410
// ( No colliders of the given type exist )
405411
if( colliderType == COLLIDER_TYPE.WALL && !this.antiColliderActive ){
406412
return forHashing;
407-
}else if( colliderType == COLLIDER_TYPE.TOP && !this.antiColliderTopActive ){
413+
}else if( colliderType == COLLIDER_TYPE.WALL_TOP && !this.antiColliderTopActive ){
408414
return forHashing;
409415
}else if( colliderType == COLLIDER_TYPE.ROOM_WARP && !this.hasRoomWarp ){
410416
return forHashing;
411417
}else if( colliderType == COLLIDER_TYPE.PORTAL_WARP && !this.hasPortalExit ){
412418
return forHashing;
419+
}else if( colliderType == COLLIDER_TYPE.HOVERABLE && !this.hasHoverables ){
420+
this.hoverableList=[];
421+
this.hoverableObj=null;
422+
this.hasClickables=false;
423+
this.clickableList=[];
424+
return forHashing;
425+
}else if( colliderType == COLLIDER_TYPE.CLICKABLE && !this.hasClickables ){
426+
return forHashing;
413427
}
414428

415429
switch( colliderType ){
@@ -431,7 +445,7 @@ class RoomEnvironment{
431445
...this.colliderList['00']
432446
];
433447
break;
434-
case COLLIDER_TYPE.TOP:
448+
case COLLIDER_TYPE.WALL_TOP:
435449
forHashing = [
436450
...this.antiColliderTopList['noAxis'],
437451
...this.antiColliderTopList['11'],

Source/js/pxlNav/cam/Camera.js

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -937,7 +937,7 @@ export class Camera{
937937
let castPos=curCamPos.clone();//.add(new Vector3(0,100,0));
938938
let castHeight=1500;
939939
castPos.y=castHeight;
940-
this.objRaycast.set(castPos, castDir );
940+
941941
let resetKeyDown=false;
942942
var rayHits=[];
943943

@@ -993,17 +993,16 @@ export class Camera{
993993
this.objectJumpLock=true;
994994
}
995995

996-
pullBack=this.cameraPos.clone();
997-
pullBack.y=Math.min(curCamPos.y,pullBack.y);//+this.cameraJumpVelocity;
998-
curCamPos=pullBack;
999-
curCollisionPos=curCamPos;
1000-
if(this.gravityActive){
1001-
curCollisionPos.y=this.nearestFloorHitPrev.y;
1002-
}else{
1003-
curCollisionPos.y=this.cameraPos.y;
1004-
}
996+
pullBack=this.cameraPos.clone();
997+
pullBack.y=Math.min(curCamPos.y,pullBack.y);//+this.cameraJumpVelocity;
998+
curCamPos=pullBack;
999+
curCollisionPos=curCamPos;
1000+
if(this.gravityActive){
1001+
curCollisionPos.y=this.nearestFloorHitPrev.y;
1002+
}else{
1003+
curCollisionPos.y=this.cameraPos.y;
1004+
}
10051005

1006-
10071006
this.cameraJumpActive=false;
10081007
this.cameraAllowJump=true;
10091008
this.cameraJumpInAir=false;

0 commit comments

Comments
 (0)