diff --git a/src/components/InteractiveObjects/GenericObject.vue b/src/components/InteractiveObjects/GenericObject.vue
index 6bda88b..bfe8ffd 100644
--- a/src/components/InteractiveObjects/GenericObject.vue
+++ b/src/components/InteractiveObjects/GenericObject.vue
@@ -8,7 +8,8 @@
-
+
{{ modelValue.title }}
@@ -19,11 +20,13 @@
export default {
data(){
return {
- active: false
+ active: false,
+ collisionTypes: []
}
},
mounted(){
this.active = true;
+ this.collisionTypes = Object.keys(this.l.collisionTypes).map(t=>({title: this.l.collisionTypes[t], value: t}))
},
props:{
modelValue: Object
diff --git a/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js b/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js
index 4310f9d..ec8aac9 100644
--- a/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js
+++ b/src/components/InteractiveObjects/MazeQuizGame/MazeQuizGame.js
@@ -42,7 +42,6 @@ class MazeQuizGame extends EventManager {
constructor(engine, data) {
super();
this.data = data;
- data.noPhysics = true;
this.params = { ...params, mazeFile: data.style || 'quiz-s2.gltf', io: this }
diff --git a/src/components/InteractiveObjects/Particles.js b/src/components/InteractiveObjects/Particles.js
index 3c9939d..afc6144 100644
--- a/src/components/InteractiveObjects/Particles.js
+++ b/src/components/InteractiveObjects/Particles.js
@@ -10,7 +10,6 @@ import * as BufferGeometryUtils from 'three/addons/utils/BufferGeometryUtils.js'
class Particles {
constructor(engine, data) {
- data.noPhysics = true;
const { x, y, count, w, h } = data;
let positions = Particles.positions(count, w, h);
return new Promise(async (resolve, reject) => {
diff --git a/src/lib/GameEngine.js b/src/lib/GameEngine.js
index 29bb9fb..8289819 100644
--- a/src/lib/GameEngine.js
+++ b/src/lib/GameEngine.js
@@ -258,7 +258,7 @@ class GameEngine extends EventManager{
event.preventDefault();
if (this.hero){
if (!this.pointerControls.isLocked){
- this.hero.cameraZ += event.deltaY / 100;
+ this.hero.cameraZ += event.deltaY * 0.005;
}
}else{
this.camera.zoom -= event.deltaY / (1000 / this.camera.zoom);
diff --git a/src/lib/GameManager.js b/src/lib/GameManager.js
index e84e3fe..ec52125 100644
--- a/src/lib/GameManager.js
+++ b/src/lib/GameManager.js
@@ -52,12 +52,7 @@ class GameManager{
let env = await engine.load(scene.data.$scene.asset.name);
this.setObjectAttributes(sceneObjects, scene.data, env.scene, env, null);
if (engine.opts.mode != 'GameDesigner'){
- env.scene.traverse(o=>{
- if (o.name.startsWith('land') || o.name == 'Sphere'){
- //this.debug('Fixing ground. TODO!!!')
- engine.physics.add(o, 'fixed', true, undefined, 'mesh', { root: env.scene})
- }
- })
+ engine.physics.apply(env.scene)
}
engine.activeObjects.add(env.scene);
}
@@ -86,13 +81,14 @@ class GameManager{
if (io.source?.animations?.length){
engine.playAnimation(engine.scene, io.source.animations[0]);
}
-
- if (!i.data.noPhysics){
+ if (i.data.collisionType == 'basic'){
let bb = engine.meshUtils.getBoundingBox(io.object);
let bbs = engine.meshUtils.getBoundingBoxSize(bb);
engine.physics.add(io.object, 'fixed', false, undefined, 'capsule', {
radius: Math.max(bbs.x, bbs.z)/2, halfHeight: bbs.y/2
})
+ }else if (i.data.collisionType == 'objectDefinied'){
+ engine.physics.apply(io.object)
}
}
io.addEventListener('finish', ()=>{
diff --git a/src/lib/Hero.js b/src/lib/Hero.js
index 343b6ee..2b3e7bd 100644
--- a/src/lib/Hero.js
+++ b/src/lib/Hero.js
@@ -13,29 +13,29 @@ class Hero{
}
set cameraZ(v){
- this.#cameraZ = Math.min(Math.max(v, 1), 12);
- if (this.#cameraZ == 1 && !this.fpv){
+ this.#cameraZ = Math.min(Math.max(v, this.cameraZMin), this.cameraZMax);
+ if (this.#cameraZ == this.cameraZMin && !this.fpv){
if (this.engine.renderer.xr.isPresenting){
this.#cameraZ = 0;
this.fpv = true;
- this.cameraY = this.size.y*0.9;
+ this.cameraY = this.cameraYBase;
this.camera.rotation.set(0,0,0);
}else{
this.engine.pointerControls.lock(true).then(()=>{
this.#cameraZ = 0;
this.fpv = true;
- this.cameraY = this.size.y*0.9;
+ this.cameraY = this.cameraYBase;
this.engine.pointerControls.once('unlock', ()=>{
this.fpv = false;
- this.cameraY = this.size.y*1.5;
+ this.cameraY = this.cameraYBase * 1.5;
})
}).catch(err=>{
console.log(err);
})
}
- }else if(this.#cameraZ > 1 && this.fpv){
+ }else if(this.#cameraZ > this.cameraZMin && this.fpv){
this.fpv = false;
- this.cameraY = this.size.y*1.5;
+ this.cameraY = this.cameraYBase * 1.5;
}
//this.engine.dashboard.updateText(this.#cameraZ);
}
@@ -67,7 +67,12 @@ class Hero{
// let center = getBoundingBoxCenterPoint(bb, this.model.userData.object.position)
let bb = engine.meshUtils.getBoundingBox(io.object);
this.size = engine.meshUtils.getBoundingBoxSize(bb);
- console.log('Hero size is', this.size);
+ //console.log('Hero size is', this.size);
+ this.cameraYBase = this.size.y / this.engine.scale;
+ this.cameraZMin = 1 / this.engine.scale;
+ this.cameraZMax = 12 / this.engine.scale;
+ this.#cameraZ = this.cameraZDefault = 4 / this.engine.scale;
+
// let center = getBoundingBoxCenterPoint(bb, io.object.position)
// console.log('hero', size, center, size.y - 2*this.characterGapOffset)
@@ -97,7 +102,7 @@ class Hero{
this.orbitControl = this.engine.orbitControls
//this.camera = this.engine.camera;
this.camera = this.engine.cameraWorld;
- this.cameraY = this.size.y * 1.5;
+ this.cameraY = this.cameraYBase * 1.5;
this.direction = this.model.rotation.y;
//this.directionVelocity = 0;
@@ -150,7 +155,7 @@ class Hero{
}
if (!this.fpv && !this.model.visible){
this.model.visible = true;
- this.#cameraZ = 4
+ this.#cameraZ = this.cameraZDefault;
this.engine.camera.fov = 45;
this.engine.camera.updateProjectionMatrix();
}
diff --git a/src/lib/Physics.js b/src/lib/Physics.js
index 58eb350..e0588f7 100644
--- a/src/lib/Physics.js
+++ b/src/lib/Physics.js
@@ -32,7 +32,7 @@ class Physics{
add = (mesh, rigidBodyType, autoAnimate = true, postPhysicsFn, colliderType, colliderSettings = {}) => {
const rigidBodyDesc = RAPIER.RigidBodyDesc[rigidBodyType]()
- let position, quaternion;
+ let position, quaternion, scale = new Vector3(1,1,1);
// if (colliderSettings.root){
// // mesh.getWorldPosition(position = new Vector3());
// // mesh.getWorldQuaternion(quaternion = new Quaternion());
@@ -42,6 +42,15 @@ class Physics{
position = mesh.position;
quaternion = mesh.quaternion;
//}
+
+ if (colliderSettings.root){
+ let p = mesh;
+ while (p != colliderSettings.root.parent) {
+ scale.multiply(p.scale);
+ p = p.parent;
+ }
+ }
+
rigidBodyDesc.setTranslation(position.x, position.y, position.z)
quaternion && rigidBodyDesc.setRotation(quaternion)
@@ -76,7 +85,7 @@ class Physics{
const position = mesh.geometry.getAttribute( 'position' );
for ( let i = 0; i < position.count; i ++ ) {
vertex.fromBufferAttribute( position, i );
- vertices.push( vertex.x, vertex.y, vertex.z );
+ vertices.push( vertex.x * scale.x, vertex.y * scale.x, vertex.z * scale.x );
}
// if the buffer is non-indexed, generate an index buffer
@@ -111,6 +120,14 @@ class Physics{
return physicsObject
}
+ apply(object){
+ object.traverse(o=>{
+ if (o.name.startsWith('land') || o.name.endsWith('-physics')){
+ this.add(o, 'fixed', true, undefined, 'mesh', { root: object})
+ }
+ })
+ }
+
clear(){
this.physicsObjects.forEach(po=>{
po.characterController && this.world.removeCharacterController(po.characterController)
diff --git a/src/plugins/lang.js b/src/plugins/lang.js
index 7b15071..044da83 100644
--- a/src/plugins/lang.js
+++ b/src/plugins/lang.js
@@ -48,7 +48,13 @@ const lang = {
minActivationScore: 'Minimum level score for activation',
viewInHUD: 'Observe in head-up display',
disableInteractions: 'Disable interactions',
- disableCollisions: 'Disable collisions',
+ collisionType: 'Collision type',
+ collisionTypes: {
+ no: 'No collisions',
+ basic: 'Basic (sphere around object)',
+ objectDefinied: 'Defined in object',
+ advanced: 'Complex (not implemented)'
+ },
dimensions: 'Dimensions',
elementsCount: 'Number of elements',
particleWidth: 'Particle width',
@@ -204,7 +210,13 @@ const lang = {
minActivationScore: 'Минимален брой точки за активиране',
viewInHUD: 'Показване в HUD (head-up display)',
disableInteractions: 'Без взаимодействия',
- disableCollisions: 'Без колизии',
+ collisionType: 'Тип колизии',
+ collisionTypes: {
+ no: 'Без',
+ basic: 'Базови (сфера около обекта)',
+ objectDefinied: 'От дефиницията на обекта',
+ advanced: 'С голяма точност (not implemented)'
+ },
dimensions: 'Размери',
elementsCount: 'Брой елементи',
particleWidth: 'Ширина на частиците',