This commit is contained in:
2025-10-19 19:19:00 +03:00
parent 953a7c22f7
commit 192a900a96
7 changed files with 113 additions and 137 deletions
Binary file not shown.
+10 -26
View File
@@ -27,23 +27,7 @@
}, },
{ {
"mesh":1, "mesh":1,
"name":"wall", "name":"wall"
"rotation":[
0,
-0.7071068286895752,
0,
0.7071068286895752
],
"scale":[
1,
1.0834307670593262,
1
],
"translation":[
0.6499999761581421,
0,
-1.100000023841858
]
}, },
{ {
"mesh":2, "mesh":2,
@@ -51,7 +35,7 @@
"translation":[ "translation":[
0, 0,
0, 0,
-0.6619032621383667 -0.772255539894104
] ]
}, },
{ {
@@ -183,14 +167,14 @@
"componentType":5126, "componentType":5126,
"count":4, "count":4,
"max":[ "max":[
-0.04999993368983269, 0.6000000238418579,
0.7055734992027283, 0.8000000715255737,
0.5996518731117249 1.196586936202948e-07
], ],
"min":[ "min":[
-0.05000001937150955, -0.6000000238418579,
-0.03282167762517929, -2.9802322387695312e-08,
-0.600348174571991 -1.233839839187567e-07
], ],
"type":"VEC3" "type":"VEC3"
}, },
@@ -253,12 +237,12 @@
"max":[ "max":[
0.5994362831115723, 0.5994362831115723,
0.8117803931236267, 0.8117803931236267,
0.6000066995620728 1.2000067234039307
], ],
"min":[ "min":[
-0.6005637049674988, -0.6005637049674988,
0.011780375614762306, 0.011780375614762306,
-0.5999934077262878 6.67572021484375e-06
], ],
"type":"VEC3" "type":"VEC3"
}, },
+1 -1
View File
@@ -224,7 +224,7 @@ export default {
vp.object.rotation.y += -Math.PI/2; vp.object.rotation.y += -Math.PI/2;
let maze = new MazeQuizGame(gameEngine, {}, [ let maze = new MazeQuizGame(gameEngine, {}, [
{s: '1 + 1 = 2', h: 'Wrong answer', a: true}, {s: 'Кое е най-голямото езеро в България', h: 'Wrong answer', a: true},
{s: '1 + 1 = 2', h: 'Wrong answer', a: true}, {s: '1 + 1 = 2', h: 'Wrong answer', a: true},
{s: '1 + 1 = 2', h: 'Wrong answer', a: true}, {s: '1 + 1 = 2', h: 'Wrong answer', a: true},
{s: '1 + 1 = 2', h: 'Wrong answer', a: true}, {s: '1 + 1 = 2', h: 'Wrong answer', a: true},
@@ -11,130 +11,116 @@ class MazeObject {
const scale = 5; const scale = 5;
context.wallSize = params.wallSize || .65*scale; context.wallSize = params.wallSize || 1.2*scale; //half
context.tubeSize = params.tubeSize || 1.2*scale; context.tubeSize = params.tubeSize || 1.2*scale;
context.wallDepth = params.wallDepth || .1*scale; context.wallDepth = params.wallDepth || 0*scale;
context.fontPath = params.fontPath || '/static/fonts/ZapfChanceryC.otf'; context.fontPath = params.fontPath || '/static/fonts/Jura-SemiBold.ttf';
const cameraNear = .2;
this.context = context; this.context = context;
let _tf = { let _tf = {
rotation: { rotation: {
r: 3 * Math.PI / 2, f: 0, l: Math.PI / 2, b: Math.PI r: 3 * Math.PI / 2, f: 0, l: Math.PI / 2, b: Math.PI
}, },
position: {
r: [-context.wallSize, context.wallSize],
f: [0, 2 * context.wallSize],
l: [context.wallSize, context.wallSize]
},
pNext: { pNext: {
r: [-context.wallSize - (context.wallSize + context.wallDepth) / 2, context.wallSize], r: [-context.wallSize/2, context.wallSize/2],
f: [0, 2 * context.wallSize + context.wallSize / 2], f: [0, context.wallSize / 2],
l: [context.wallSize + (context.wallSize + context.wallDepth) / 2, context.wallSize] l: [context.wallSize/2, context.wallSize/2]
} }
}; };
let o = {}; let o = {};
let areas = [], mazeMeshes = []; let areas = [], mazeMeshes = [];
function addPhysics(matrix, position, size, placement = 'side'){
let quat = new Quaternion().setFromRotationMatrix(matrix);
let v = new Vector3(...position).applyMatrix4(matrix);
let po = engine.phy.add(
{position: v}, 'fixed', false, undefined, 'cuboid',{ width: 0.01, height:1, depth:size/2 }
)
if (placement == 'front') {
quat.multiply(new Quaternion(0, 0.7071068, 0, 0.7071068)) //rotate by 90deg
}
po.rigidBody.setRotation(quat, true)
}
this.mazeObject = function(def, room, step = 0) { this.mazeObject = function(def, room, step = 0) {
if (!def.matrix){
def.matrix = new Matrix4();
}
let offsetZ = 0, e; let offsetZ = 0, e;
def.len = def.len || 0; def.len = def.len || 0;
if (step == 0) { // if (step == 0) {
e = o.door.clone(); // e = o.door.clone();
e.rotateY(_tf.rotation.f); // e.rotateY(_tf.rotation.f);
mazeMeshes.push(e); // mazeMeshes.push(e);
} // }
for (let i = 0; i < def.len; i++) { for (let i = 0; i < def.len; i++) {
let t = o.tunnel.clone(); let t = o.tunnel.clone();
t.position.set(0, 0, i * context.tubeSize + context.wallDepth / 2); t.position.set(0, 0, i * context.tubeSize);
def.matrix && t.applyMatrix4(def.matrix); def.matrix && t.applyMatrix4(def.matrix);
mazeMeshes.push(t); mazeMeshes.push(t);
} }
offsetZ = context.wallDepth + def.len * context.tubeSize - context.tubeSize / 2; offsetZ = def.len * context.tubeSize;
if (!def.len) offsetZ = -.275; //if (!def.len) offsetZ = -.275;
areas.push({ //room.getWorldQuaternion(quat);
a: [ // const geometry = new BoxGeometry(2, 2, offsetZ);
room.localToWorld(new Vector3(-context.tubeSize / 2 + cameraNear, 0, -context.tubeSize / 2 - cameraNear)), // const cube = new Mesh(geometry, o.tunnel.material)
room.localToWorld(new Vector3(context.tubeSize / 2 - cameraNear, 0, offsetZ + cameraNear)) // cube.position.set(context.tubeSize / 2, 0.6, offsetZ/2)
] // root.add(cube);
});
let quat = new Quaternion(); // console.log(offsetZ, room.localToWorld(new Vector3(context.tubeSize / 2, 0.6, offsetZ/2)))
room.getWorldQuaternion(quat);
console.log('adding!!!', room.localToWorld(new Vector3(context.tubeSize / 2, 0.6, offsetZ/2)), quat) let ofZ = def.len * context.tubeSize
addPhysics(def.matrix, [context.tubeSize / 2, 0.6, offsetZ/2], offsetZ)
addPhysics(def.matrix, [-context.tubeSize / 2, 0.6, offsetZ/2], offsetZ)
// const geometry = new BoxGeometry(2, 2, offsetZ); e = [
// const cube = new Mesh(geometry, o.tunnel.material) o.floor.clone(),
// cube.position.set(context.tubeSize / 2, 0.6, offsetZ/2) o.door.clone(),
// root.add(cube); o[def.r ? 'door' : 'wall'].clone(),
o[def.f ? 'door' : 'wall'].clone(),
o[def.l ? 'door' : 'wall'].clone()
];
// console.log(offsetZ, room.localToWorld(new Vector3(context.tubeSize / 2, 0.6, offsetZ/2))) e[0].position.set(0, 0, offsetZ + context.wallSize/2);
let left = engine.phy.add( e[1].rotateY(_tf.rotation.b);
{position: room.localToWorld(new Vector3(context.tubeSize / 2, 0.6, offsetZ/2))},
'fixed', false, undefined, 'cuboid',{ width: 0.01, height:1, depth:offsetZ/2 }
)
left.rigidBody.setRotation(quat, true)
let right = engine.phy.add( e[2].rotateY(_tf.rotation.r);
{position: room.localToWorld(new Vector3(-context.tubeSize / 2, 0.6, offsetZ/2))}, e[3].rotateY(_tf.rotation.f);
'fixed', false, undefined, 'cuboid',{ width: 0.01, height:1, depth:offsetZ/2 } e[4].rotateY(_tf.rotation.l);
)
right.rigidBody.setRotation(quat, true)
e[1].position.set(0, 0, offsetZ + 0);
if (def.type == 'area') { e[2].position.set(-context.wallSize/2, 0, offsetZ + context.wallSize/2);
def.area.forEach(ar => { e[3].position.set(0, 0, offsetZ + context.wallSize);
areas.push({ e[4].position.set(context.wallSize/2, 0, offsetZ + context.wallSize/2);
a: [
room.localToWorld(new Vector3(ar[0] + cameraNear, 0, offsetZ + ar[1] - cameraNear)),
room.localToWorld(new Vector3(ar[2] - cameraNear, 0, offsetZ + ar[3] + cameraNear))
]
});
});
} else {
if (def.noRoom) {
// e = o.wall.geometry.clone();
// e.rotateY(_tf.rotation.f);
// e.translate(0,0,offsetZ + 0);
// def.matrix && e.applyMatrix4(def.matrix);
// mazeGeometries.push(e);
} else {
e = [o.floor.clone(), o.door.clone(), o[def.r ? 'door' : 'wall'].clone(),
o[def.f ? 'door' : 'wall'].clone(), o[def.l ? 'door' : 'wall'].clone()];
e[0].position.set(0, 0, offsetZ + context.wallSize);
e[1].rotateY(_tf.rotation.b); if (!def.r){
e[2].rotateY(_tf.rotation.r); addPhysics(def.matrix, [-context.wallSize/2, 0, offsetZ + context.wallSize/2], context.wallSize)
e[3].rotateY(_tf.rotation.f);
e[4].rotateY(_tf.rotation.l);
e[1].position.set(0, 0, offsetZ + 0);
e[2].position.set(-context.wallSize, 0, offsetZ + context.wallSize);
e[3].position.set(0, 0, offsetZ + context.wallSize * 2);
e[4].position.set(context.wallSize, 0, offsetZ + context.wallSize);
e.forEach(g => {
def.matrix && g.applyMatrix4(def.matrix);
mazeMeshes.push(g);
});
areas.push({
a: [
room.localToWorld(new Vector3(-context.wallSize + cameraNear, 0, offsetZ + cameraNear)),
room.localToWorld(new Vector3(context.wallSize - cameraNear, 0, offsetZ + context.wallSize * 2 - cameraNear))
]
});
}
} }
if (!def.f){
addPhysics(def.matrix, [0, 0, offsetZ + context.wallSize], context.wallSize, 'front')
}
if (!def.l){
addPhysics(def.matrix, [context.wallSize/2, 0, offsetZ + context.wallSize/2], context.wallSize)
}
e.forEach(g => {
def.matrix && g.applyMatrix4(def.matrix);
mazeMeshes.push(g);
});
def.objects && def.objects.forEach(obj => { def.objects && def.objects.forEach(obj => {
obj.room = room; obj.room = room;
// let go = new GameObject(obj, context); // let go = new GameObject(obj, context);
let go = new TextObject(obj, context) let go = new TextObject(obj, context)
room.add(go.mesh); go.mesh.scale.multiplyScalar(scale)
go.mesh.position.multiply(new Vector3(scale, scale, context.wallSize))
go.mesh.applyMatrix4(def.matrix);
root.add(go.mesh);
// go.ready.then(mesh => { // go.ready.then(mesh => {
// room.add(mesh); // room.add(mesh);
// }); // });
@@ -148,7 +134,7 @@ class MazeObject {
mtx.setPosition(_tf.pNext[d][0], 0, _tf.pNext[d][1] + offsetZ); mtx.setPosition(_tf.pNext[d][0], 0, _tf.pNext[d][1] + offsetZ);
let rr = new Group(); let rr = new Group();
root.add(rr); root.add(rr);
def[d].matrix = mtx.premultiply(def.matrix || new Matrix4()); def[d].matrix = mtx.premultiply(def.matrix);
rr.applyMatrix4(def[d].matrix); rr.applyMatrix4(def[d].matrix);
rr.updateMatrixWorld(); rr.updateMatrixWorld();
this.mazeObject(def[d], rr, step + 1); this.mazeObject(def[d], rr, step + 1);
@@ -159,8 +145,10 @@ class MazeObject {
let mazeAsset = await engine.load('/static/meshes/maze-reed.gltf'); let mazeAsset = await engine.load('/static/meshes/maze-reed.gltf');
['tunnel', 'wall', 'door', 'floor'].forEach(e => { ['tunnel', 'wall', 'door', 'floor'].forEach(e => {
o[e] = mazeAsset.scene.getObjectByName(e); o[e] = mazeAsset.scene.getObjectByName(e);
o[e].frustumCulled = false; //o[e].frustumCulled = false;
o[e].scale.set(scale, scale, scale) o[e].scale.set(scale, scale, scale)
// o[e].geometry.computeBoundingBox();
// console.log(e, o[e].geometry.boundingBox)
}); });
this.mazeObject(def, room); this.mazeObject(def, room);
mazeMeshes.forEach(mesh=>{ mazeMeshes.forEach(mesh=>{
@@ -23,7 +23,7 @@ class MazeQuizGame {
len, len,
objects:[ objects:[
{ {
type: 'text', text: cq.s, position:[0,.44,len-0.2], rotation:[0,Math.PI, 0] type: 'text', text: cq.s, position:[0,.44,len], rotation:[0,Math.PI, 0]
} }
], ],
[lrv?'r':'l']:{ [lrv?'r':'l']:{
@@ -32,7 +32,7 @@ class MazeQuizGame {
len: lr, len: lr,
objects:[ objects:[
{ {
type: 'text', text: cq.h, position:[0,.44,lr-0.2], rotation:[0,Math.PI, 0] type: 'text', text: cq.h, position:[0,.44,lr], rotation:[0,Math.PI, 0]
} }
] ]
} }
+17 -17
View File
@@ -28,23 +28,23 @@ class TextObject {
txt.sync(); txt.sync();
this.txt = txt; this.txt = txt;
this.mesh = txt; this.mesh = txt;
if (obj.effect == 'distance') { // if (obj.effect == 'distance') {
let dstm = .8; // let dstm = .8;
var oldBR = txt.onBeforeRender; // var oldBR = txt.onBeforeRender;
txt.material[1].opacity = 0.01; // txt.material[1].opacity = 0.01;
txt.onBeforeRender = function (renderer, scene, camera) { // txt.onBeforeRender = function (renderer, scene, camera) {
oldBR && oldBR.apply(this, arguments); // oldBR && oldBR.apply(this, arguments);
var v = new Vector3(); // var v = new Vector3();
txt.getWorldPosition(v); // txt.getWorldPosition(v);
var dst = camera.position.distanceTo(v); // var dst = camera.position.distanceTo(v);
if (dst < dstm * 2 && dst > dstm * 1) { // if (dst < dstm * 2 && dst > dstm * 1) {
txt.material[1].opacity = dstm * 1 - (dst - dstm * 1); // txt.material[1].opacity = dstm * 1 - (dst - dstm * 1);
} // }
if (dst < .5 * dstm) { // if (dst < .5 * dstm) {
txt.material[1].opacity = dstm * dst * 2; // txt.material[1].opacity = dstm * dst * 2;
} // }
}; // };
} // }
} }
} }
+6 -2
View File
@@ -101,9 +101,11 @@ export class CharacterControls {
this.model.position.z + 5* Math.cos(angleYCameraDirection + directionOffset) this.model.position.z + 5* Math.cos(angleYCameraDirection + directionOffset)
) )
cameraPosition.lerp(cameraDesiredPosition, delta*3) cameraPosition.lerp(cameraDesiredPosition, delta*2)
if (Math.abs(cameraPosition.x - this.model.position.x) + Math.abs(cameraPosition.z - this.model.position.z) > 2){ let dst = Math.sqrt(Math.pow(cameraPosition.x - this.model.position.x, 2) + Math.pow(cameraPosition.z - this.model.position.z, 2));
//cameraPosition.y = 8 - dst;
if (dst > 2){
this.camera.position.copy(cameraPosition) this.camera.position.copy(cameraPosition)
this.camera.lookAt(new THREE.Vector3( this.camera.lookAt(new THREE.Vector3(
this.model.position.x, this.model.position.x,
@@ -111,6 +113,8 @@ export class CharacterControls {
this.model.position.z this.model.position.z
)) ))
} }
//this.camera.zoom = dst
//this.camera.updateProjectionMatrix();
// run/walk velocity // run/walk velocity
velocity = this.currentAction == 'run' ? this.runVelocity : this.walkVelocity velocity = this.currentAction == 'run' ? this.runVelocity : this.walkVelocity