[] []
Imagine those are the front tires of a car and they're spinning forward in a straight line. How would I rotate them (in a steering motion) without them being affected by their local (spinning) rotation?
Add a "wheel" to a THREE.Group() object and rotate the group on y-axis.
for(var i = 0; i < wheels.length; i++){
steering[i].rotation.y = Math.sin(new Date() * 0.005) * 0.25;
wheels[i].rotation.x += 0.1;
}
each steering is a THREE.Group(), each wheels is a cylinder.
jsfiddle example
Related
I'm working with three.js, attempting to model a real world camera. As such, I'd like to limit its axis of rotation to 90 degrees along x and y axises.
Is there a simply way to do this? My current code isn't working particularly well (and goes crazy when you attempt to move the camera past the X and Y boundaries simultaneously)
if(xRot != null && xRot != undefined){
camera.rotateX(xRot);
}
if(yRot != null && yRot != undefined){
camera.rotateY(yRot);
}
if(camera.rotation.x < minCameraRotX){
camera.rotation.x = minCameraRotX;
}else if (camera.rotation.x > maxCameraRotX){
camera.rotation.x = maxCameraRotX;
}
if(camera.rotation.y < minCameraRotY){
camera.rotation.y = minCameraRotY;
}else if(camera.rotation.y > maxCameraRotY){
camera.rotation.y = maxCameraRotY;
}
Any advice would be greatly appreciated!!!
I actually managed to find a solution by checking some of the existing code in a Three.js demo for a library called PointerLock. The idea is to actually stack multiple objects inside each other: start with an object that moves horizontally (the yaw object), place another object inside the yaw object that moves vertically (the pitch object), and then place the actual camera inside the pitch object.
Then, you only rotate the outside objects (yaw and pitch) along their respective axises, so if you rotate both, they'll self-correct. For example, if you rotate the yaw 45 degrees along the y-axis (making it turn to the right) and then rotate the pitch 45 degrees (making it turn downward), the pitch will go 45 degrees downward from the yaw's already rotated position.
Given that the camera is inside both, it just points wherever the yaw and pitch direct it.
Here is the code
/*
* CAMERA SETUP
*
* Root object is a Yaw object (which controls horizontal movements)
* Yaw object contains a Pitch object (which controls vertical movement)
* Pitch object contains camera (which allows scene to be viewed)
*
* Entire setup works like an airplane with a
* camera embedded in the propellor...
*
*/
// Yaw Object
var yawObject = new THREE.Object3D();
// Pitch Object
var pitchObject = new THREE.Object3D();
// Camera Object
var camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
// Max Camera angles (in radians)
var minCameraRotX = 0.5;
var maxCameraRotX = 0.5;
var minCameraRotY = 1;
var maxCameraRotY = 1;
// Setup
yawObject.add( pitchObject );
pitchObject.add( camera );
scene.add(yawObject);
...
var rotateCamera = function(xRot, yRot, zRot){
yawObject.rotation.y += yRot;
pitchObject.rotation.x += xRot;
// Enforce X-axis boundaries (rotates around y-axis)
yawObject.rotation.y = Math.max( minCameraRotY, Math.min( maxCameraRotY, yawObject.rotation.y ) );
// Enforce Y-axis boundaries (rotates around x-axis)
pitchObject.rotation.x = Math.max( minCameraRotX, Math.min( maxCameraRotX, pitchObject.rotation.x ) );
}
Here is the source code I referenced: https://github.com/mrdoob/three.js/blob/acda8a7c8f90ce9b71088e903d8dd029e229678e/examples/js/controls/PointerLockControls.js
Also, this is sort of cheesy, but this little plane cartoon helped me visual exactly what was going on in my setup
I want to focus the camera on THREE.Geometry, one vertex at a time and
Transition the camera to the next vertex of the same Geometry
How should i accomplish 1 & 2?
I created a fiddle.
http://jsfiddle.net/5oajajpd/
the function move camera goes through each vertex and sets the camera position. To transition this with animation you can set the x,y, and z properties through the jquery animate function, or your animation lib of choice.
The move camera function is triggered by an interval. In this sphere example it will spiral around and around the sphere forever.
var i = 0;
function moveCamera() {
var point = mesh.geometry.vertices[i];
var coeff = 1 + altitude / rad;
camera.position.x = point.x * coeff;
camera.position.y = point.y * coeff;
camera.position.z = point.z * coeff;
camera.lookAt(mesh.position);
i++;
if (i > mesh.geometry.vertices.length) {
i = 0;
}
}
I write an algorithm that can explode (fold and unfold) mechanical set by double clicking on then.
But i want to move the camera backward or forward after that to see all my objects in the fov.
I'm trying to use frustum to calculate intersection between frustum and objects, but i don't undestand how to use planes.
I'm working with OrthographicCamera.
What i do :
At every frame i recalculate the new frustum (when camera move):
projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
frustum.setFromMatrix(projScreenMatrix);
Then i do a loop over the 6 planes and bounding box of all objects in the scene :
for (var i = 0; i < planes.length; i++) {
var plane = planes[i];
for (var j = 0; j < boxs.length; j++) {
var box = boxs[j];
var line = new THREE.Line3(box.min, nox.max);
//console.log({'plane': plane, 'line': line});
if (plane.isIntersectionLine(line))
// move camera
};
};
but plane.isIntersectionLine(line) is always false.
Do you have any ideas ?
Thanks
I'm trying to make a static 3D prism out of point clouds with specific numbers of particles in each. I've got the the corner coordinates of each side of the prism based on the angle of turn, and tried spawning the particles in the area bound by these coordinates. Instead, the resulting point clouds have kept only the bottom left coordinate.
Screenshot: http://i.stack.imgur.com/uQ7Q8.png
I've tried to set the rotation of each cloud object such that their edges meet, but they will rotate only around the world centre. I gather this is something to do with rotation matrices and Euler angles, but, having been trying to work them out for 3 solid days, I've despaired. (I'm a sociologist, not a dev, and haven't touched graphics before this project.)
Please help? How do I set the rotation on each face of the prism? Or maybe there is a more sensible way to get the particles to spawn in the correct area in the first place?
The code:
// draw the particles
var n = 0;
do {
var geom = new THREE.Geometry();
var material = new THREE.PointCloudMaterial({size: 1, vertexColors: true, color: 0xffffff});
for (i = 0; i < group[n]; i++) {
if (geom.vertices.length < group[n]){
var particle = new THREE.Vector3(
Math.random() * screens[n].bottomrightback.x + screens[n].bottomleftfront.x,
Math.random() * screens[n].toprightback.y + screens[n].bottomleftfront.y,
Math.random() * screens[n].bottomrightfront.z + screens[n].bottomleftfront.z);
geom.vertices.push(particle);
geom.colors.push(new THREE.Color(Math.random() * 0x00ffff));
}
}
var system = new THREE.PointCloud(geom, material);
scene.add(system);
**// something something matrix Euler something?**
n++
}
while (n < numGroups);
I've tried to set the rotation of each cloud object such that their
edges meet, but they will rotate only around the world centre.
It is true they only rotate around 0,0,0. The simple solution then is to move the object to the center, rotate it, and then move it back to its original position.
For example (Code not tested so might take a bit of tweaking):
var m = new THREE.Matrix4();
var movetocenter = new THREE.Matrix4();
movetocenter.makeTranslation(-x, -y, -z);
var rotate = new THREE.Matrix4();
rotate.makeRotationFromEuler(); //Build your rotation here
var moveback = new THREE.Matrix4();
moveback .makeTranslation(x, y, z);
m.multiply(movetocenter);
m.multiply(rotate);
m.multiply(moveback);
//Now you can use geometry.applyMatrix(m)
I have a mesh set that is in a Object3D when i get the vertices they are not centered on the object. so i need to compute the center of the object3D then move the meshes to align them to the center. I have tried computing the boundingboxes of each Mesh then max - min /2; this does not work. Any help here would be fantastic. I have tried the Object3D.setFromObject(); this only return infinity.
To center an Object3D, depending on its children, you have to iterate through them, as far as I know. The code would look like the following:
// myObject3D is your Object3D
var children = myObject3D.children,
completeBoundingBox = new THREE.Box3(); // create a new box which will contain the entire values
for(var i = 0, j = children.length; i < j; i++){ // iterate through the children
children[i].geometry.computeBoundingBox(); // compute the bounding box of the the meshes geometry
var box = children[i].geometry.boundingBox.clone(); // clone the calculated bounding box, because we have to translate it
box.translate(children[i].position); // translate the geometries bounding box by the meshes position
completeBoundingBox.addPoint(box.max).addPoint(box.min); // add the max and min values to your completeBoundingBox
}
var objectCenter = completeBoundingBox.center()
console.log('This is the center of your Object3D:', objectCenter );
// You want the center of you bounding box to be at 0|0|0
myObject3D.position.x -= objectCenter.x;
myObject3D.position.y -= objectCenter.y;
myObject3D.position.z -= objectCenter.z;
Hope I understood your problem right!
center = function(obj) {
var children = obj.children,
completeBoundingBox = new THREE.Box3();
for(var i = 0, j = children.length; i < j; i++) {
children[i].geometry.computeBoundingBox();
var box = children[i].geometry.boundingBox.clone();
box.translate(children[i].position);
completeBoundingBox.set(box.max, box.min);
}
var objectCenter = completeBoundingBox.center()
console.log('This is the center of your Object3D:', objectCenter );
obj.position.x -= objectCenter.x;
obj.position.y -= objectCenter.y;
obj.position.z -= objectCenter.z;
}