THREE.JS Cannot read property 'matrixWorld' of undefined - three.js

When I create a sprite, OrbitControls works perfectly.
But when I switch to FirstPersonControls, everything freezes and the console gives this error:
Uncaught TypeError: Cannot read property 'matrixWorld' of undefined
at Sprite.raycast (three.js:26051)
at intersectObject (three.js:44583)
at Raycaster.intersectObjects (three.js:44658)
at animate (mainview.php?project_id=46&tipo=1:936)
Raycasting code:
if (firstorbit) {
if (l % 5 == 0) {
var vector = new THREE.Vector3(0, -1, 0);
vector = camera.localToWorld(vector);
vector.sub(camera.position);
var raycasterGround = new THREE.Raycaster(camera.position, vector);
var intersectsGround = raycasterGround.intersectObjects(scene.children, true);
if (intersectsGround.length > 0) {
if (intersectsGround[0].distance < 1.21) {
camera.position.y = (camera.position.y + (1.21 - intersectsGround[0].distance));
}
if (intersectsGround[0].distance > 1.36 && intersectsGround[0].distance < 1.45) {
camera.position.y = (camera.position.y - (intersectsGround[0].distance - 1.215));
}
}
}
if (l % 3 == 0) {
var vector1 = new THREE.Vector3(0, 0, -1);
vector1 = camera.localToWorld(vector1);
vector1.sub(camera.position);
var raycasterFront = new THREE.Raycaster(camera.position, vector1);
var intersectsFront = raycasterFront.intersectObjects(scene.children, true);
if (intersectsFront.length > 0) {
if (intersectsFront[0].distance < 0.3) {
controls.moveForward = false;
controls.w = false;
} else {
controls.w = true;
}
} else controls.w = true;
}
}
Raycasting code that I use on mouse click to measure something:
function getIntersections( event ) {
var vectorMouse = new THREE.Vector2();
vectorMouse.set(
mouse.x,
mouse.y );
var raycasterClick = new THREE.Raycaster();
raycasterClick.setFromCamera( vectorMouse, camera );
var intersectsClick = raycasterClick.intersectObjects( scene.children,true );
return intersectsClick;
}
I am not sure if the problem is with the sprite or with my raycasting code. But when I remove the sprite, everything works perfectly. And when I remove the Raycasting code, everything also works perfectly.

Related

Ammo Threejs Breakable objects debis set material after breaking in fragments

i have initially breakable object with nice texture material loaded.
After breaking in fragments lost original material and load some default material.
Any suggest?
I use code from threejs example with ammo:
Source code:
import * as THREE from "three";
import {ConvexObjectBreaker} from "../jsm/misc/ConvexObjectBreaker";
import {updatePhysics} from "./updater";
export class MagicPhysics {
// Physics variables
gravityConstant = 7.8;
collisionConfiguration;
dispatcher;
broadphase;
solver;
physicsWorld;
margin = 0.05;
convexBreaker = new ConvexObjectBreaker();
// Rigid bodies include all movable objects
rigidBodies = [];
pos = new THREE.Vector3();
quat = new THREE.Quaternion();
transformAux1;
tempBtVec3_1;
objectsToRemove = [];
// Player
ammoTmpPos;
ammoTmpQuat;
tmpTrans;
numObjectsToRemove = 0;
impactPoint = new THREE.Vector3();
impactNormal = new THREE.Vector3();
// kinekt type of movement
kMoveDirection = {left: 0, right: 0, forward: 0, back: 0};
// velocity type of movement
moveDirection = {left: 0, right: 0, forward: 0, back: 0};
tmpPos = new THREE.Vector3();
tmpQuat = new THREE.Quaternion();
constructor(options) {
console.log("MagicPhysics =>", options)
this.updatePhysics = updatePhysics.bind(this);
this.config = options.config;
}
initPhysics() {
// Physics configuration
this.collisionConfiguration = new Ammo.btDefaultCollisionConfiguration();
this.dispatcher = new Ammo.btCollisionDispatcher(this.collisionConfiguration);
this.broadphase = new Ammo.btDbvtBroadphase();
const solver = new Ammo.btSequentialImpulseConstraintSolver();
this.physicsWorld = new Ammo.btDiscreteDynamicsWorld(
this.dispatcher,
this.broadphase,
solver,
this.collisionConfiguration
);
this.physicsWorld.setGravity(new Ammo.btVector3(0, -this.gravityConstant, 0));
this.transformAux1 = new Ammo.btTransform();
this.tempBtVec3_1 = new Ammo.btVector3(0, 0, 0);
}
createRigidBody(object, physicsShape, mass, pos, quat, vel, angVel) {
if(pos) {
object.position.copy(pos);
} else {
pos = object.position;
}
if(quat) {
object.quaternion.copy(quat);
} else {
quat = object.quaternion;
}
const transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(pos.x, pos.y, pos.z));
transform.setRotation(
new Ammo.btQuaternion(quat.x, quat.y, quat.z, quat.w)
);
const motionState = new Ammo.btDefaultMotionState(transform);
const localInertia = new Ammo.btVector3(0, 0, 0);
physicsShape.calculateLocalInertia(mass, localInertia);
const rbInfo = new Ammo.btRigidBodyConstructionInfo(
mass,
motionState,
physicsShape,
localInertia
);
const body = new Ammo.btRigidBody(rbInfo);
body.setFriction(0.5);
if(vel) {
body.setLinearVelocity(new Ammo.btVector3(vel.x, vel.y, vel.z));
}
if(angVel) {
body.setAngularVelocity(
new Ammo.btVector3(angVel.x, angVel.y, angVel.z)
);
}
object.userData.physicsBody = body;
object.userData.collided = false;
this.scene.add(object);
if(mass > 0) {
this.rigidBodies.push(object);
// Disable deactivation
body.setActivationState(4);
}
this.physicsWorld.addRigidBody(body);
return body;
}
createConvexHullPhysicsShape(coords) {
const shape = new Ammo.btConvexHullShape();
for(let i = 0, il = coords.length;i < il;i += 3) {
this.tempBtVec3_1.setValue(coords[i], coords[i + 1], coords[i + 2]);
const lastOne = i >= il - 3;
shape.addPoint(this.tempBtVec3_1, lastOne);
}
return shape;
}
createParalellepipedWithPhysics(sx, sy, sz, mass, pos, quat, material) {
const object = new THREE.Mesh(
new THREE.BoxGeometry(sx, sy, sz, 1, 1, 1),
material
);
const shape = new Ammo.btBoxShape(
new Ammo.btVector3(sx * 0.5, sy * 0.5, sz * 0.5)
);
shape.setMargin(this.margin);
this.createRigidBody(object, shape, mass, pos, quat);
return object;
}
createDebrisFromBreakableObject(object) {
object.castShadow = true;
object.receiveShadow = true;
const shape = this.createConvexHullPhysicsShape(
object.geometry.attributes.position.array
);
shape.setMargin(this.margin);
const body = this.createRigidBody(
object,
shape,
object.userData.mass,
null,
null,
object.userData.velocity,
object.userData.angularVelocity
);
// Set pointer back to the three object only in the debris objects
const btVecUserData = new Ammo.btVector3(0, 0, 0);
btVecUserData.threeObject = object;
body.setUserPointer(btVecUserData);
}
removeDebris(object) {
this.scene.remove(object);
this.physicsWorld.removeRigidBody(object.userData.physicsBody);
}
}

html/css-/js drag and drop for mouse and touch combine with rotate with every click?

I use a script for moving an object both with mouse and touch screen. This works.
I have another script to make the object rotate 90 degrees with each click, this also works.
It just doesn't work together.
When I merge them, the move still works, but with a click the object moves back to the starting position and only rotates there.
I've read that I should merge this but I don't know how. Below both scripts.
Thanks in advance for responses.
var container = document.querySelector("#container");
var activeItem = null;
var active = false;
container.addEventListener("touchstart", dragStart, false);
container.addEventListener("touchend", dragEnd, false);
container.addEventListener("touchmove", drag, false);
container.addEventListener("mousedown", dragStart, false);
container.addEventListener("mouseup", dragEnd, false);
container.addEventListener("mousemove", drag, false);
function dragStart(e) {
if (e.target !== e.currentTarget) {
active = true;
// this is the item we are interacting with
activeItem = e.target;
if (activeItem !== null) {
if (!activeItem.xOffset) {
activeItem.xOffset = 0;
}
if (!activeItem.yOffset) {
activeItem.yOffset = 0;
}
if (e.type === "touchstart") {
activeItem.initialX = e.touches[0].clientX - activeItem.xOffset;
activeItem.initialY = e.touches[0].clientY - activeItem.yOffset;
} else {
console.log("doing something!");
activeItem.initialX = e.clientX - activeItem.xOffset;
activeItem.initialY = e.clientY - activeItem.yOffset;
}
}
}
}
function dragEnd(e) {
if (activeItem !== null) {
activeItem.initialX = activeItem.currentX;
activeItem.initialY = activeItem.currentY;
}
active = false;
activeItem = null;
}
function drag(e) {
if (active) {
if (e.type === "touchmove") {
e.preventDefault();
activeItem.currentX = e.touches[0].clientX - activeItem.initialX;
activeItem.currentY = e.touches[0].clientY - activeItem.initialY;
} else {
activeItem.currentX = e.clientX - activeItem.initialX;
activeItem.currentY = e.clientY - activeItem.initialY;
}
activeItem.xOffset = activeItem.currentX;
activeItem.yOffset = activeItem.currentY;
setTranslate(activeItem.currentX, activeItem.currentY, activeItem);
}
}
function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
}
// Make blocks rotate 90 deg on each click
var count=0;
function rot(e){
count++;
var deg=count*90;
e.style.transform = "rotate("+deg+"deg)";
}
So I put them in a file but then it only works as described above.

Cannon js move physical body with animation

I'm trying to figure this out for a while now and I just can't find a solution.
I'm working with three JS and the Cannon Library.
I created a simple object/ mesh with a tween animation. With the Cannon Library I added a physical body to the mesh.
I put an animation an the mesh so it changes the rotation but the rotation of the physical body just doesn't change at all.
second position
First position
This is where I define the physics:
class Physics {
constructor() {
this.world = new CANNON.World();
this.stepSize = 0;
this.timeToGo = 0;
this.visualObjects = [];
this.physicalBodies = [];
}
addPair(visualObject, body) {
this.visualObjects.push(visualObject);
this.physicalBodies.push(body);
}
initialize(gravityX, gravityY, gravityZ, stepsize, addfloor) {
this.world.gravity.set(gravityX, gravityY, gravityZ);
this.world.broadphase = new CANNON.NaiveBroadphase();
his.stepSize = stepsize;
if (addfloor) {
var floor = new CANNON.Body({
shape: new CANNON.Plane(),
mass: 0
});
floor.quaternion.setFromAxisAngle(new CANNON.Vec3(1, -0, 0), -Math.PI / 2);
floor.position.y = -32;
this.world.addBody(floor);
}
}
update(delta) {
// Step physics world forward
this.timeToGo += delta;
while (this.timeToGo >= this.stepSize) {
this.world.step(this.stepSize);
this.timeToGo -= this.stepSize;
}
// Copy transformations
for (var i = 0; i < this.visualObjects.length; i++) {
this.visualObjects[i].position.copy(this.physicalBodies[i].position);
this.visualObjects[i].quaternion.copy(this.physicalBodies[i].quaternion);
}
}
getWorld() {
return this.world;
}
addStandPhysical(visualObject, mass){
var shapeAblage = new CANNON.Box(new CANNON.Vec3(0.5*2,0.5*8,0.5*40));
var shapeMittelstrebe = new CANNON.Box(new CANNON.Vec3(0.5*10,0.5*1,0.5*100));
var shapeAblage3 = new CANNON.Box(new CANNON.Vec3(0.5*2.5,0.5*1,0.5*15));
var shapeAblage4 = new CANNON.Box(new CANNON.Vec3(0.5*2.5,0.5*1,0.5*15));
var shapeFuss5 = new CANNON.Box(new CANNON.Vec3(0.5*2.5,0.5*1,0.5*15));
var shapeMittelding = new CANNON.Cylinder(2,2,25,32)
var body = new CANNON.Body({ mass: mass });
body.addShape(shapeAblage, new CANNON.Vec3(-1.25, 29, 41), new CANNON.Quaternion().setFromEuler( 0, 90*DEG_TO_RAD,90*DEG_TO_RAD, "XYZ")); //ablage1
body.addShape(shapeAblage, new CANNON.Vec3(-1.25, 29, -41), new CANNON.Quaternion().setFromEuler( 0, 90*DEG_TO_RAD,90*DEG_TO_RAD, "XYZ")); //ablage2
body.addShape(shapeAblage, new CANNON.Vec3(-1.25, -29, -41), new CANNON.Quaternion().setFromEuler( 0, 90*DEG_TO_RAD,90*DEG_TO_RAD, "XYZ")); //ablage3
body.addShape(shapeAblage, new CANNON.Vec3(-1.25, -29, 41), new CANNON.Quaternion().setFromEuler( 0, 90*DEG_TO_RAD,90*DEG_TO_RAD, "XYZ")); //ablage4
body.addShape(shapeMittelstrebe, new CANNON.Vec3( 1.75, 0, 0), new CANNON.Quaternion().setFromEuler(35* DEG_TO_RAD, 0, 0, "XYZ"));
body.addShape(shapeMittelstrebe, new CANNON.Vec3( -1.75, 0, 0), new CANNON.Quaternion().setFromEuler(-35* DEG_TO_RAD, 0, 0, "XYZ"));
body.position.copy(visualObject.position);
body.quaternion.copy(visualObject.quaternion);
this.world.addBody(body);
this.addPair(visualObject, body);
}
}
And this is basically my main:
function main() {
scene = new THREE.Scene();
physics = new Physics();
physics.initialize(0, -200, 0, 1 / 120, floor = false); //Hier mit der Stepsize vielleicht noch ein wenig experimentieren und herausfinden, was sie macht
physicsVisualDebugger = new THREE.CannonDebugRenderer(scene, physics.getWorld());
var stand = new Stand();
physics.addStandPhysical(stand,3);
scene.add(stand);
var clock = new THREE.Clock();
function mainLoop() {
stats.begin();
var delta = clock.getDelta();
physics.update(delta);
physicsVisualDebugger.update();
stand.animations.forEach(function (animation) {
animation.update(delta);
});
TWEEN.update();
renderer.render(scene, camera);
stats.end();
requestAnimationFrame(mainLoop);
}
}
So long question short: how do I get the physical Bodies to move with my animation of the meshes to the ground?
I consider but maybe I am wrong, that your two arrays
this.visualObjects, this.physicalBodies
have not the same length. So maybe the update loop do not copy right the positions and quaternions. Better use the loop this way:
world.bodies.forEach( function(body) { ... }
to get looped exact the bodies.

Three.js - can I detect geometry 'islands' when importing?

I'm importing .3DS models into Blender 2.72b, then exporting them with the Three.js import/export addon. The models have multiple geometry 'islands' (separate groups of connected faces and vertices), each with its own material. I'd like to be able to pair each material with its corresponding island, without having to create separate THREE.Geometry objects. After some digging, I found this question which suggests using a THREE.MeshFaceMaterial to achieve multiple materials for one object. The only problem is that the geometry in that example is a simple cube, whereas my models have hundreds of faces spread across 2-5 islands.
Does Three.js have functionality for identifying geometry 'islands' in a mesh?
No. three.js does not have functionality for identifying geometry 'islands' in a mesh.
When using MeshFaceMaterial, WebGLRenderer breaks the geometry into chunks anyway -- one chunk for each material. It does that because WebGL supports one shader per geometry.
I would not merge all your geometries, and then use MeshFaceMaterial, only to have the renderer break the single geometry apart.
You can merge geometries that share a single material if you wish.
three.js r.69
I tried with a function but still is not accurate, it produce more geometries than non connected geometries:
If somebody could have a look on it, it would be grate.
function groupGeometryIntoNonConnectedGeometries(geometry) {
const material = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
vertexColors: THREE.VertexColors
});
let geometryArray = [];
const indexArray = geometry.index.array;
const positionArray = geometry.attributes.position.array;
const positionCount = geometry.attributes.position.count;
const color = new THREE.Vector3(geometry.attributes.color.array[0], geometry.attributes.color.array[1], geometry.attributes.color.array[2]);
const totalTriangles = indexArray.length / 3;
let geometryCount = 0;
let indexValueAlreadyVisited = new Uint8Array(indexArray.length);
let structure = [];
/*
* indexValue: {
* child: [ [indexval0, indexval1], [] ],
* parent: null
* }
*/
// Initialize Structure:
for (var vextexIdx=0; vextexIdx<positionCount; vextexIdx++) {
structure[vextexIdx] = {
child: [],
parent: null
}
}
for (idx=0; idx<totalTriangles; idx++) {
const geoIndex1 = indexArray[idx*3];
const geoIndex2 = indexArray[idx*3+1];
const geoIndex3 = indexArray[idx*3+2];
const triangleIndexVertexArray = [ geoIndex1, geoIndex2, geoIndex3 ].sort(function(a, b) {
return a - b;
});
structure[ triangleIndexVertexArray[0] ].child.push(triangleIndexVertexArray[1], triangleIndexVertexArray[2]);
structure[ triangleIndexVertexArray[1] ].parent = triangleIndexVertexArray[0];
structure[ triangleIndexVertexArray[2] ].parent = triangleIndexVertexArray[0];
}
let count = 0;
let currentCount = 0;
let geometryStructureArray = [];
for (let strIdx=0; strIdx<structure.length; strIdx++) {
if (structure[strIdx].parent == null) {
currentCount = count;
geometryStructureArray[currentCount] = {
name: "G_" + currentCount,
indexMap: {},
currentIndex: 0,
indexArray: [],
positionArray: [],
colorArray: []
};
count += 1;
}
if (structure[strIdx].child.length > 0) {
const childLen = structure[strIdx].child.length / 2;
for (let childIdx=0; childIdx<childLen; childIdx++) {
const vertexIndex0 = strIdx;
const vertexIndex1 = structure[strIdx].child[childIdx*2];
const vertexIndex2 = structure[strIdx].child[childIdx*2+1];
const v0 = new THREE.Vector3( positionArray[strIdx*3], positionArray[strIdx*3+1], positionArray[strIdx*3+2] );
const v1 = new THREE.Vector3( positionArray[vertexIndex1*3], positionArray[vertexIndex1*3+1], positionArray[vertexIndex1*3+2] );
const v2 = new THREE.Vector3( positionArray[vertexIndex2*3], positionArray[vertexIndex2*3+1], positionArray[vertexIndex2*3+2] );
// check vertex0
if (geometryStructureArray[currentCount].indexMap[vertexIndex0] == undefined) {
geometryStructureArray[currentCount].indexMap[vertexIndex0] = geometryStructureArray[currentCount].currentIndex;
geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].currentIndex);
geometryStructureArray[currentCount].positionArray.push(v0.x, v0.y, v0.z);
geometryStructureArray[currentCount].colorArray.push(color.x, color.y, color.z);
geometryStructureArray[currentCount].currentIndex += 1;
} else {
geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].indexMap[vertexIndex0]);
}
// check vertex1
if (geometryStructureArray[currentCount].indexMap[vertexIndex1] == undefined) {
geometryStructureArray[currentCount].indexMap[vertexIndex1] = geometryStructureArray[currentCount].currentIndex;
geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].currentIndex);
geometryStructureArray[currentCount].positionArray.push(v1.x, v1.y, v1.z);
geometryStructureArray[currentCount].colorArray.push(color.x, color.y, color.z);
geometryStructureArray[currentCount].currentIndex += 1;
} else {
geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].indexMap[vertexIndex1]);
}
// check vertex1
if (geometryStructureArray[currentCount].indexMap[vertexIndex2] == undefined) {
geometryStructureArray[currentCount].indexMap[vertexIndex2] = geometryStructureArray[currentCount].currentIndex;
geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].currentIndex);
geometryStructureArray[currentCount].positionArray.push(v2.x, v2.y, v2.z);
geometryStructureArray[currentCount].colorArray.push(color.x, color.y, color.z);
geometryStructureArray[currentCount].currentIndex += 1;
} else {
geometryStructureArray[currentCount].indexArray.push(geometryStructureArray[currentCount].indexMap[vertexIndex2]);
}
}
}
}
// Convert to geometryArray:
const geometryStructureArrayLen = geometryStructureArray.length;
const object3d = new THREE.Object3D();
for (let geoIdx=0; geoIdx<geometryStructureArrayLen; geoIdx++) {
const geo = new THREE.BufferGeometry();
geo.name = "G_" + geoIdx;
const geoPositions = new Float32Array(geometryStructureArray[geoIdx].positionArray);
const geoColors = new Float32Array(geometryStructureArray[geoIdx].colorArray);
const geoIndices = new Uint32Array(geometryStructureArray[geoIdx].indexArray);
//console.log(geoIdx, "geoPositions: ", geoPositions);
//console.log(geoIdx, "geoColors: ", geoColors);
//console.log(geoIdx, "geoIndices: ", geoIndices);
geo.index = new THREE.BufferAttribute(geoIndices, 1, false);
geo.attributes.position = new THREE.BufferAttribute(geoPositions, 3, false);
geo.attributes.color = new THREE.BufferAttribute(geoColors, 3, true);
geo.computeBoundingSphere();
geo.computeBoundingBox();
const mesh = new THREE.Mesh(geo, material);
mesh.name = "M_" + geoIdx;
object3d.add(mesh);
}
//return [structure, geometryStructureArray, object3d, count];
return object3d;
}
Best regards
This is I think the correct way:
function unmergeGeometryArray(geometry) {
// Asumptions:
// geometry is BufferGeometry
// The geometry has no index duplicates (2 equal positions with different index) neither empty triangles, the geometry has been processed with mergeVertices function
// normal attribute is discarded, can be recomputed after, only color and position attributes are taken into account
const material = new THREE.MeshBasicMaterial({
side: THREE.DoubleSide,
vertexColors: THREE.VertexColors
});
const indexArray = geometry.index.array;
const positionArray = geometry.attributes.position.array;
const positionCount = geometry.attributes.position.count;
const totalTriangles = indexArray.length / 3;
let triangleVisitedArray = new Uint8Array(totalTriangles);
let indexVisitedArray = new Uint8Array(positionCount);
let indexToTriangleIndexMap = [];
let missingVertices = positionCount;
let missingTriangles = totalTriangles;
// Functions:
function computeTrianglesRecursive(index, out){
//console.log("- start of computeTriangles with index:", index);
if (indexVisitedArray[index] === 1 || missingVertices === 0 || missingTriangles === 0) {
return;
}
indexVisitedArray[index] = 1;
missingVertices -= 1;
let triangleIndexArray = indexToTriangleIndexMap[index];
for(let i=0; i<indexToTriangleIndexMap[index].length; i++) {
let triangleIndex = indexToTriangleIndexMap[index][i];
if (triangleVisitedArray[triangleIndex] === 0) {
triangleVisitedArray[triangleIndex] = 1
missingTriangles -= 1;
//console.log("-- index: ", index, "; i: ", i, "; triangleIndex: ", triangleIndex);
out.push(triangleIndex);
childIndex1 = indexArray[triangleIndex*3+1];
computeTriangles(childIndex1, out);
childIndex2 = indexArray[triangleIndex*3+2];
computeTriangles(childIndex2, out);
}
}
}
function computeTriangles(indexTocheck){
let out = [];
let startIndex = indexTocheck;
let indexToCheckArray = [indexTocheck];
let i = 0;
while (i<indexToCheckArray.length) {
let index = indexToCheckArray[i];
if (indexVisitedArray[index] == 0) {
indexVisitedArray[index] = 1;
missingVertices -= 1;
let triangleIndexArray = indexToTriangleIndexMap[index];
for(let j=0; j<indexToTriangleIndexMap[index].length; j++) {
let triangleIndex = indexToTriangleIndexMap[index][j];
if (triangleVisitedArray[triangleIndex] === 0) {
triangleVisitedArray[triangleIndex] = 1;
missingTriangles -= 1;
out.push(triangleIndex);
let rootIndex = indexArray[triangleIndex*3];
let child1Index = indexArray[triangleIndex*3+1];
let child2Index = indexArray[triangleIndex*3+2];
if (indexToCheckArray.indexOf(rootIndex) === -1) {
indexToCheckArray.push(rootIndex);
}
if (indexToCheckArray.indexOf(child1Index) === -1) {
indexToCheckArray.push(child1Index);
}
if (indexToCheckArray.indexOf(child2Index) === -1) {
indexToCheckArray.push(child2Index);
}
}
}
}
i +=1;
}
return out;
}
// In the first loop we reorder indices asc order + generate map
for (triangleIndex=0; triangleIndex<totalTriangles; triangleIndex++) {
const geoIndex1 = indexArray[triangleIndex*3];
const geoIndex2 = indexArray[triangleIndex*3+1];
const geoIndex3 = indexArray[triangleIndex*3+2];
const triangleIndexVertexArray = [ geoIndex1, geoIndex2, geoIndex3 ].sort(function(a, b) {
return a - b;
});
if (indexToTriangleIndexMap[geoIndex1] === undefined) {
indexToTriangleIndexMap[geoIndex1] = [triangleIndex];
} else {
indexToTriangleIndexMap[geoIndex1].push(triangleIndex);
}
if (indexToTriangleIndexMap[geoIndex2] === undefined) {
indexToTriangleIndexMap[geoIndex2] = [triangleIndex];
} else {
indexToTriangleIndexMap[geoIndex2].push(triangleIndex);
}
if (indexToTriangleIndexMap[geoIndex3] === undefined) {
indexToTriangleIndexMap[geoIndex3] = [triangleIndex];
} else {
indexToTriangleIndexMap[geoIndex3].push(triangleIndex);
}
//indexArray[triangleIndex*3] = triangleIndexVertexArray[0];
//indexArray[triangleIndex*3+1] = triangleIndexVertexArray[1];
//indexArray[triangleIndex*3+2] = triangleIndexVertexArray[2];
}
let geometryTriangleArray = [];
let index = 0;
while (index<indexToTriangleIndexMap.length && missingVertices>0 && missingTriangles>0){
let out = [];
if (indexVisitedArray[index] === 0) {
out = computeTriangles(index);
}
if (out.length > 0) {
geometryTriangleArray.push(out);
}
index += 1;
}
let geometryArray = [];
for (let i=0; i<geometryTriangleArray.length; i++) {
let out = {
positionArray: [],
colorArray: [],
indexArray: [],
indexMap: [],
currentIndex: 0
}
let triangleArray = geometryTriangleArray[i];
for (let j=0; j<triangleArray.length; j++) {
let triangleIndex = triangleArray[j];
let rootIndex = indexArray[triangleIndex*3];
if (out.indexMap[rootIndex] === undefined) {
out.indexMap[rootIndex] = out.currentIndex;
// add vertex position and color
out.positionArray.push(
geometry.attributes.position.array[rootIndex*3],
geometry.attributes.position.array[rootIndex*3+1],
geometry.attributes.position.array[rootIndex*3+2]
);
if (geometry.attributes.color != undefined) {
out.colorArray.push(
geometry.attributes.color.array[rootIndex*3],
geometry.attributes.color.array[rootIndex*3+1],
geometry.attributes.color.array[rootIndex*3+2]
);
}
out.currentIndex += 1;
}
let child1Index = indexArray[triangleIndex*3+1];
if (out.indexMap[child1Index] === undefined) {
out.indexMap[child1Index] = out.currentIndex;
// add vertex position and color
out.positionArray.push(
geometry.attributes.position.array[child1Index*3],
geometry.attributes.position.array[child1Index*3+1],
geometry.attributes.position.array[child1Index*3+2]
);
if (geometry.attributes.color != undefined) {
out.colorArray.push(
geometry.attributes.color.array[child1Index*3],
geometry.attributes.color.array[child1Index*3+1],
geometry.attributes.color.array[child1Index*3+2]
);
}
out.currentIndex += 1;
}
let child2Index = indexArray[triangleIndex*3+2];
if (out.indexMap[child2Index] === undefined) {
out.indexMap[child2Index] = out.currentIndex;
// add vertex position and color
out.positionArray.push(
geometry.attributes.position.array[child2Index*3],
geometry.attributes.position.array[child2Index*3+1],
geometry.attributes.position.array[child2Index*3+2]
);
if (geometry.attributes.color != undefined) {
out.colorArray.push(
geometry.attributes.color.array[child2Index*3],
geometry.attributes.color.array[child2Index*3+1],
geometry.attributes.color.array[child2Index*3+2]
);
}
out.currentIndex += 1;
}
// Add indices:
out.indexArray.push(out.indexMap[rootIndex], out.indexMap[child1Index], out.indexMap[child2Index]);
}
const geoPositions = new Float32Array(out.positionArray);
const geoColors = new Float32Array(out.colorArray);
const geoIndices = new Uint32Array(out.indexArray);
const geo = new THREE.BufferGeometry();
geo.name = "G_" + i;
geo.index = new THREE.BufferAttribute(geoIndices, 1, false);
geo.attributes.position = new THREE.BufferAttribute(geoPositions, 3, false);
geo.attributes.color = new THREE.BufferAttribute(geoColors, 3, true);
geo.computeBoundingSphere();
geo.computeBoundingBox();
geometryArray.push(geo);
}
return geometryArray;
}

Three js camera movement

i dont have the code here so i hope you can understand, i'l edit and add the code when i get home.
I have built a class move that once initialized adds a jquery event (keyDown) to the rendered dom element.
the event checks what key is down in a switch case,
if the key is one of the cases the camera will be moved accordingly.
The camera does move, but for some reason it flickers a bit, like little jumps.
the speed for each camera move is 0.05;
when i did this in anouter app but via a javascript keydown event from the main script (no special class) it worked fine..
any idea why would it do this ?
edit: code
main script :
<script>
var moveMec = null;
var loopProg = null;
var renderer = null;
var scene = null;
var camera = null;
var mesh = null;
var earth = null;
var sun = null;
$(document).ready(
function() {
var container = document.getElementById("container");
renderer = new THREE.WebGLRenderer({ antialias: true } );
renderer.setSize(container.offsetWidth,container.offsetHeight);
container.appendChild(renderer.domElement)
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 45,
container.offsetWidth / container.offsetHeight, 1, 4000 );
earth = new Earth();
sun = new Sun({x:-10,y:0,z:20});
scene.add(earth.getEarth);
scene.add(sun.sunLight);
camera.position.set( 0, 0, 3 );
moveMec = new moveMechanics(camera,renderer.domElement)
loopProg = new loopProgram();
loopProg.add(function(){earth.update()});
//loopProg.add(function(){renderer.render( scene, camera );});
loopProg.solarLoop();
}
);
</script>
move script :
var moveMechanics = function (camera,domElement,speed)
{
moveMechanics.camera = camera;
moveMechanics.speed = speed != undefined ? speed : 0.01;
moveMechanics.domElement = domElement;
$(document).keydown(function(event)
{
switch(event.which)
{
case KeyEvent.DOM_VK_W:
camera.position.z -= moveMechanics.speed;
break;
case KeyEvent.DOM_VK_S:
camera.position.z += moveMechanics.speed;
break;
case KeyEvent.DOM_VK_D:
camera.position.x += moveMechanics.speed;
break;
case KeyEvent.DOM_VK_A:
camera.position.x -= moveMechanics.speed;
break;
}
});
}
loop code :
function loopProgram()
{
this.functionsToRun = new Array();
this.solarLoop= function()
{
jQuery.each(loopProg.functionsToRun, function(index,value)
{
value ? value() : null;
});
requestAnimationFrame(loopProg.solarLoop);
}
this.add = function(func)
{
this.functionsToRun[this.functionsToRun.length] = func;
}
}

Resources