BabylonJS Collision Detection, Overlapping Meshes - javascript

In the following example: http://www.babylonjs-playground.com/#1NASOD#13
Why does the sphere mesh overlap (or fall slightly into) the box mesh as the box moves upwards? Is there a way to make the sphere not overlap the box as the box moves the sphere upwards?
For reference, here is the relevant code from the example:
var createScene = function () {
// This creates a basic Babylon Scene object (non-mesh)
var scene = new BABYLON.Scene(engine);
// This creates and positions a free camera (non-mesh)
var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 10, -20), scene);
// This targets the camera to scene origin
camera.setTarget(BABYLON.Vector3.Zero());
// This attaches the camera to the canvas
camera.attachControl(canvas, true);
// This creates a light, aiming 0,1,0 - to the sky (non-mesh)
var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
// Default intensity is 1. Let's dim the light a small amount
light.intensity = 0.7;
// Our built-in 'sphere' shape. Params: name, subdivs, size, scene
var sphere = BABYLON.Mesh.CreateSphere("sphere1", 8, 2, scene);
// Move the sphere upward 1/2 its height
sphere.position.y = 2;
var ground = BABYLON.Mesh.CreateBox("box1",2.0, scene);
ground.position.y = -1;
sphere.material = new BABYLON.StandardMaterial("s-mat", scene);
scene.enablePhysics(new BABYLON.Vector3(0, 0, 0));
sphere.physicsImpostor = new BABYLON.PhysicsImpostor(sphere, BABYLON.PhysicsImpostor.SphereImpostor, { mass: 1, restitution: 0 }, scene);
ground.physicsImpostor = new BABYLON.PhysicsImpostor(ground, BABYLON.PhysicsImpostor.BoxImpostor, { mass: 0, restitution: 0 }, scene);
scene.registerBeforeRender(function () {
if(ground.position.y <= 2.5){
ground.position.y += .05;
}
sphere.physicsImpostor.setLinearVelocity(new BABYLON.Vector3(0,0,0));
sphere.physicsImpostor.setAngularVelocity(new BABYLON.Quaternion(0,0,0,0));
});
return scene;
};

Related

How does three.js render video according to spherical UV?

I have a dash streaming video. According to its title, it is a 3*3. Now I can splice the complete video through the THREE,
// 3*3 PlaneGeometry
var geometry = new THREE.PlaneGeometry(400, 200, 3, 3);
const video1 = document.getElementById("videos1");
...................
...................
const texture1 = new THREE.VideoTexture(video3);
texture1.maxFilter = THREE.NearestFilter;
texture1.minFilter = THREE.NearestFilter;
...................
...................
var geometryfaces = geometry.faces;
for (let i = 0; i < geometryfaces.length; i++) {
const faces = geometryfaces[i];
materials[i] = new THREE.MeshBasicMaterial({
map: textures[i],
});
}
var uv = [
new THREE.Vector2(0, 0),
new THREE.Vector2(0, 1),
new THREE.Vector2(1, 1),
new THREE.Vector2(1, 0),
];
// Set the texture coordinates
for (var m = 0; m < geometryfaces.length; m += 2) {
geometry.faces[m].materialIndex = faceId;
console.log(geometry.faces);
geometry.faces[m + 1].materialIndex = faceId;
geometry.faceVertexUvs[0][m] = [uv[2], uv[3], uv[1]];
geometry.faceVertexUvs[0][m + 1] = [uv[3], uv[0], uv[1]];
faceId++;
}
var bufferGeometry = new THREE.BufferGeometry().fromGeometry(geometry);
var material = new THREE.MeshFaceMaterial(materials);
var mesh = new THREE.Mesh(bufferGeometry, material); //网格模型对象Mesh
This way I can get a full flat video, but this video is panoramic and I need to render it on the ball, and I don't know much about the UV of the ball。
I need help. Thank you
picture:enter image description here
picture2:enter image description here
Three.js SphereGeometry automatically creates the UV mapping for you. Since the image you're using is equirectangular, you can just map the image onto the inside of the sphere for the effect you want:
var camera, scene, renderer, vp, sphere;
vp = new THREE.Vector2(window.innerWidth, window.innerHeight);
// Init WebGL stuff
function init() {
// WebGL Renderer
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(vp.x, vp.y);
renderer.domElement.classList.add("canvasWebGL");
// append to DOM
document.body.appendChild(renderer.domElement);
// scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0xe1e1e1);
// camera
camera = new THREE.PerspectiveCamera(55, vp.x / vp.y, 0.05, 100);
// Sphere radius is large enough to surround the camera
let sphereGeom = new THREE.SphereGeometry( 20, 128, 128 );
// Just use your equirect image as the texture
// And render the INSIDE of the sphere, not the outside
const tex = new THREE.TextureLoader().load("https://i.imgur.com/1VECsLy.jpg");
let sphereMat = new THREE.MeshBasicMaterial({
map: tex,
side: THREE.BackSide
});
sphere = new THREE.Mesh(sphereGeom, sphereMat);
scene.add(sphere);
}
function animate(s) {
sphere.rotation.set(
Math.cos(s / 3000), s / 3000, 0
);
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
init();
animate(0);
<script src="https://cdn.jsdelivr.net/npm/three#0.123/build/three.js"></script>
Read more about sphere geometry here: https://threejs.org/docs/?q=material#api/en/geometries/SphereGeometry

Camera rotation toward mesh sometimes bugs very hard - Using Three.js and Tween.js for 360° pictures player

I'm using Three.js to develop a player for 360° pictures.
My scene contains a sphere (BasicMeshMaterial) that has a 360° picture as texture. The camera is in the middle of that sphere, so that the user sees the picture, that is applied to the sphere's "walls".
I recently added the possibility to click on some spots of the sphere, to rotate the camera towards that spot. The camera smoothly moves to this spot, untill it has this spot in the center of the screen.
My problem is that sometimes the camera easing (tween animation) that is supposed to focus the spot clicked uses a very strange path and it's all very ugly.
This seems to happen when the initial position of the camera and the target position cross a certain point of the sphere. I have almost no clue what happens. Do you ? Could it have a link with the sphere, or the camera is only playing with quaternions and so it's not affected by others objects ? Then what could make it chose wrong path, and how come it happens only with a certain angle of the sphere ? anything would be help !
The player is testable at http://isiko.io/, after scrolling a bit.
I can show you the code but don't really know what to pick. Tell me if you need the camera's rotation,or the sphere's initiation..
Thank you for your feedbacks.
There is another approach with tweening an angle around an axis:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 0);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var sphere = new THREE.Mesh(new THREE.SphereGeometry(10, 32, 24), new THREE.MeshBasicMaterial({
color: "yellow",
wireframe: true
}));
scene.add(sphere);
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
var center = new THREE.Vector3();
var vectorStart = new THREE.Vector3(0, 0, -10); // in front of the camera
var vectorEnd = new THREE.Vector3();
var angle = {
value: 0
};
var angleEnd = {
value: 0
};
var normal = new THREE.Vector3();
var lookAt = new THREE.Vector3();
var isMoving = false;
window.addEventListener("mousedown", onMouseDown, false);
function onMouseDown(event) {
if (isMoving) return;
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
let newPosition = raycaster.ray.at(10);
setPoint(newPosition);
// prepare the values we need for tweening
vectorEnd.copy(newPosition);
angle.value = 0; // we will tween this value
angleEnd.value = vectorStart.angleTo(vectorEnd); // to this one
normal.copy(vectorStart).cross(vectorEnd).normalize(); // around this axis
// tween the angle
var tween = new TWEEN.Tween(angle).to(angleEnd, 1000).delay(250).easing(TWEEN.Easing.Cubic.InOut).onStart(function(){
isMoving = true;
}).onUpdate(
function() {
camera.lookAt(lookAt.copy(vectorStart).applyAxisAngle(normal, angle.value));
}
).onComplete(function() {
isMoving = false;
vectorStart.copy(vectorEnd);
}).start();
}
function setPoint(position) {
let point = new THREE.Mesh(new THREE.SphereGeometry(0.125, 4, 2), new THREE.MeshBasicMaterial({
color: "red",
wireframe: true
}));
point.position.copy(position);
scene.add(point);
}
render()
function render() {
requestAnimationFrame(render);
TWEEN.update(); // don't forget to put this line into the animation loop, when you use Tween.js
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.min.js"></script>

Threejs apply clipping to specific area of the object

I'm using THREE.Plane to clip my STL model.
localPlane = new THREE.Plane( new THREE.Vector3( 0, -1, 0 ), 4);
.
.
.
material = new THREE.MeshPhongMaterial( {
color: 0xffffff,
side: THREE.DoubleSide,
clippingPlanes: [
localPlane,
],
clipShadows: true
} );
It's working; but the problem is that the whole object's top is clipped by this infinity sized plane. I want it to clip just a small part of it (It seems that there is no way to scale THREE.Plane)
I also tried using ThreeCSG.js but it seems inconvenient with STL objects!
Here is what I get:
Yes, the removal of the intersection of clipping planes is supported in three.js. You can use a pattern like this one:
// clipping planes
var localPlanes = [
new THREE.Plane( new THREE.Vector3( - 1, 0, 0 ), 1 ),
new THREE.Plane( new THREE.Vector3( 0, - 1, 0 ), 1 )
];
// material
var material = new THREE.MeshPhongMaterial( {
color: 0xffffff,
side: THREE.DoubleSide,
clippingPlanes: localPlanes,
clipIntersection: true
} );
Also, see the three.js example.
three.js r.85
Edit: Follow WestLangley's advice. I'll leave this her as an alternate though less efficient means of performing the clipping.
Clipping planes are infinite. There's no getting around that. So what can you do? Multiple clipping planes in multiple render passes!
To do this, you'll need to turn off auto-clearing, and do your own manual buffer clearing.
renderer = new THREE.WebGLRenderer();
renderer.autoClear = false;
Now let's say plane1 is the clipping plane you currently have.
material = new THREE.MeshPhongMaterial( {
...
clippingPlanes: [
plane1,
],
clipShadows: true
} );
var myMesh = new THREE.Mesh(geometry, material);
That clips the top half of myMesh when you call render. So you want to work with the remainder.
First, make another plane, plane2, be the inverse of plane1. plane2 will then clip the BOTTOM of myMesh. But if you render one pass using plane1, and another using plane2, then you're back with a full mesh. So you'll need a third clip plane, plane3, which clips only the desired half of myMesh. Putting plane2 and plane3 in the same render pass will result in only 1/4 of myMesh rendering.
var pass1ClipPlanes = [
plane1
],
pass2ClipLanes = [
plane2, // this plane is the inverse of plane 1, so it clips the opposite of plane1
plane3 // this clips the left/right half of the model
];
Then when you go to render, clear the draw buffers first, then call two render passes, updating the clip planes between them.
// clear the draw buffers
renderer.clear();
// clip the top
myMesh.material.clipPlanes = pass1ClipPlanes;
renderer.render(scene, camera);
// clip the bottom and one side
myMesh.material.clipPlanes = pass2ClipPlanes;
renderer.render(scene, camera);
The first pass renders the bottom of the model, and the second pass renders half of the top.
ETA: Example
var renderer, scene, camera, controls, stats;
var cube,
pass1ClipPlanes,
pass2ClipPlanes;
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight,
FOV = 35,
NEAR = 1,
FAR = 1000;
function init() {
document.body.style.backgroundColor = "slateGray";
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.localClippingEnabled = true;
renderer.autoClear = false;
document.body.appendChild(renderer.domElement);
document.body.style.overflow = "hidden";
document.body.style.margin = "0";
document.body.style.padding = "0";
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
camera.position.z = 50;
scene.add(camera);
controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.dynamicDampingFactor = 0.5;
controls.rotateSpeed = 3;
var light = new THREE.PointLight(0xffffff, 1, Infinity);
camera.add(light);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0';
document.body.appendChild(stats.domElement);
resize();
window.onresize = resize;
// POPULATE EXAMPLE
var plane1 = new THREE.Plane(new THREE.Vector3(0, -1, 0), 0),
plane2 = new THREE.Plane(new THREE.Vector3(0, 1, 0), 0),
plane3 = new THREE.Plane(new THREE.Vector3(-1, 0, 0), 0);
pass1ClipPlanes = [plane1];
pass2ClipPlanes = [plane2, plane3];
var cubeGeo = new THREE.BoxBufferGeometry(10, 10, 10),
cubeMat = new THREE.MeshPhongMaterial({
color: "red",
side: THREE.DoubleSide
});
cube = new THREE.Mesh(cubeGeo, cubeMat);
scene.add(cube);
animate();
}
function resize() {
WIDTH = window.innerWidth;
HEIGHT = window.innerHeight;
if (renderer && camera && controls) {
renderer.setSize(WIDTH, HEIGHT);
camera.aspect = WIDTH / HEIGHT;
camera.updateProjectionMatrix();
controls.handleResize();
}
}
function render() {
renderer.clear();
cube.material.clippingPlanes = pass1ClipPlanes;
renderer.render(scene, camera);
cube.material.clippingPlanes = pass2ClipPlanes;
renderer.render(scene, camera);
}
function animate() {
requestAnimationFrame(animate);
render();
controls.update();
stats.update();
}
function threeReady() {
init();
}
(function() {
function addScript(url, callback) {
callback = callback || function() {};
var script = document.createElement("script");
script.addEventListener("load", callback);
script.setAttribute("src", url);
document.head.appendChild(script);
}
addScript("https://threejs.org/build/three.js", function() {
addScript("https://threejs.org/examples/js/controls/TrackballControls.js", function() {
addScript("https://threejs.org/examples/js/libs/stats.min.js", function() {
threeReady();
})
})
})
})();

Light rays from point light three.js

Is there a way to see the light rays from a point light in a Three js scene. I have tried fog but it makes the whole objects in the scene the color of fog.
var width = $('#g_pre_emo').width();
var scene = new THREE.Scene();
scene.fog = new THREE.Fog(0xffff00, 0, 10);
var camera = new THREE.PerspectiveCamera(50, width / 500, 0.1, 1000);
var renderer = new THREE.WebGLRenderer({antialias: false});
renderer.setSize(width, 500);
$('#g_pre_emo').append(renderer.domElement);
var intensity = 2.5;
var distance = 5;
var decay = 2.0;
var light = new THREE.AmbientLight(0x404040); // soft white light
scene.add(light);
renderer.shadowMap.Enabled = true;
renderer.setClearColor(0xffffff, 1);
var happyGroup = new THREE.Object3D();
var sadGroup = new THREE.Object3D();
var angryGroup = new THREE.Object3D();
var relaxedGroup = new THREE.Object3D();
scene.add(happyGroup);
scene.add(sadGroup);
scene.add(angryGroup);
scene.add(relaxedGroup);
var c1 = 0xffff00;
var sphere = new THREE.SphereGeometry(0.25, 16, 8);
light1 = new THREE.PointLight(c1, intensity, distance, decay);
light1.add(new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({color: c1})));
scene.add(light1);
happyGroup.position.set(-3, 3, 0);
sadGroup.position.set(3, 3, 0);
angryGroup.position.set(-3, -3, 0);
relaxedGroup.position.set(3, -3, 0);
var happyGeometry = new THREE.SphereGeometry(1, 50, 50);
var happyMaterial = new THREE.MeshNormalMaterial();
var happySphere = new THREE.Mesh(happyGeometry, happyMaterial);
scene.add(happySphere);
happyGroup.add(happySphere);
var sadGeometry = new THREE.SphereGeometry(1, 50, 50);
var sadMaterial = new THREE.MeshNormalMaterial();
var sadSphere = new THREE.Mesh(sadGeometry, sadMaterial);
scene.add(sadSphere);
sadGroup.add(sadSphere);
var angryGeometry = new THREE.SphereGeometry(1, 50, 50);
var angryMaterial = new THREE.MeshNormalMaterial();
var angrySphere = new THREE.Mesh(angryGeometry, angryMaterial);
scene.add(angrySphere);
angryGroup.add(angrySphere);
var relaxedGeometry = new THREE.SphereGeometry(1, 50, 50);
var relaxedMaterial = new THREE.MeshNormalMaterial();
var relaxedSphere = new THREE.Mesh(relaxedGeometry, relaxedMaterial);
scene.add(relaxedSphere);
relaxedGroup.add(relaxedSphere);
renderer.gammaInput = true;
renderer.gammaOutput = true;
camera.position.z = 15;
function render() {
renderer.render(scene, camera);
}
;
render();
animate();
function animate() {
requestAnimationFrame(animate);
}
If i run the above code the i cant see any fog in the scene
the fiddle for above code is
https://jsfiddle.net/bqv5ynbo/1/
Possibly, you can use VolumetricSpotlightMaterial from Jerome Etienne.
For me it worked well for Three.js r71, though I haven't tried it with later revisions.
Example of usage
'Light Rays' aren't an automatically occurring thing.
Typically, light rays are created using advanced pixel shaders (stencil/shadow projection over lit region / volumetric fog) or in simple cases by creating simple alpha-blended polygons with 'ray' textures applied.
A point light is simply a light that does not apply directional calculations during it's shading phase. Instead, only distance based calculations are made.
Good Luck!

Three.js Object3d cylinder rotation to align to a vector

I have searched far and wide, but can't seem to figure this pretty basic thing out. I have seen other examples on stackoverflow and elsewhere from a year or two ago, but they fail to work with the latest version of Three.js.
Here is a version of what i'm working on: http://medschoolgunners.com/sandbox/3d/.
I'm trying to get the grey cone to exactly align with the unlabeled red vector. Ie. I want the tip of the cone to be exactly aligned with the vector and point out from the origin in that direction.
Here is the code I have right now:
//FUNCTION TO CREATE A CYLINDER
function create_cylinder(radiusTop,radiusBottom, height, segmentsRadius, segmentsHeight, openEnded, color)
{
var material = new THREE.MeshLambertMaterial({
color: color, //0x0000ff
opacity: 0.2
});
var cylinder = new THREE.Mesh(new THREE.CylinderGeometry(radiusTop,radiusBottom, height, segmentsRadius, segmentsHeight, openEnded), material);
cylinder.overdraw = true;
return cylinder;
}
//ALIGN THE CYLINDER TO A GIVEN VECTOR
var alignVector=new THREE.Vector3(-50,50,50); //the vector to be aligned with
var newcylinder = create_cylinder(0.1, 10, 40, 50, 50, false, "0x0ff0f0"); // the object to be aligned with the vector above
var cylinderQuaternion = new THREE.Quaternion();
cylinderQuaternion.setFromEuler(alignVector);
newcylinder.useQuaternion = true;
newcylinder.quaternion=cylinderQuaternion;
scatterPlot.add(newcylinder);
If you have an arbitrary vector:
var vector = new THREE.Vector3(100, 60, 20);
You can align an object, such as a cylinder, to the vector like this:
var geometry = new THREE.CylinderGeometry(2, 2, vector.length(), 4, 4);
var mesh = new THREE.Mesh(geometry, someMaterial);
var axis = new THREE.Vector3(0, 1, 0);
mesh.quaternion.setFromUnitVectors(axis, vector.clone().normalize());
Where axis is the original direction of the cylinder (pointing up).
You can also move the cylinder to match the position of the vector like this:
mesh.position.copy(vector.clone().multiplyScalar(0.5));
This puts one end of the cylinder at the 0, 0, 0 and the other at 100, 60, 20, and works because I set the cylinder length to vector.length().
i know this is an old question, but in case anyone is still wondering, what worked for me was adding the vector to the mesh position and use lookAt to align it to the vector:
//Mesh to align
var material = new THREE.MeshLambertMaterial({color: 0x0000ff});
var cylinder = new THREE.Mesh(new THREE.CylinderGeometry(10, 10, 15), material);
//vector to align to
var vector = new THREE.Vector3(
5,//x
10,//y
15 //z
);
//create a point to lookAt
var focalPoint = new THREE.Vector3(
cylinder.position.x + vector.x,
cylinder.position.y + vector.y,
cylinder.position.z + vector.z
);
//all that remains is setting the up vector (if needed) and use lookAt
cylinder.up = new THREE.Vector3(0,0,1);//Z axis up
cylinder.lookAt(focalPoint);
Unfortunately I haven't worked with Quaternions, so can't help much. It seems to my that some offsetting is needed, since the cylinder's pivot is at the centre of the mesh, not at one end.
If played with matrices a bit, and I've got decent results.
Here's one way to this, using Mesh's lookAt() method:
var HALF_PI = -Math.PI * .5;
var p1 = new THREE.Vector3(Math.random()-.5,Math.random()-.5,Math.random()-.5).multiplyScalar(30);
var p2 = new THREE.Vector3(Math.random(),Math.random(),Math.random()).multiplyScalar(300);
var halfLength = diff.length() * .5;
var c = new THREE.CylinderGeometry(10, 10, halfLength * 2, 12, 1, false );
var orientation = new THREE.Matrix4();
orientation.setRotationFromEuler(new THREE.Vector3(HALF_PI,0,0));//rotate on X 90 degrees
orientation.setPosition(new THREE.Vector3(0,0,halfLength));//move half way on Z, since default pivot is at centre
c.applyMatrix(orientation);//apply transformation for geometry
var m = new THREE.Mesh( c, new THREE.MeshLambertMaterial( { color: 0x009900, wireframe: true, shading: THREE.FlatShading } ) );
scene.add(m);
m.lookAt(p2);//tell mesh to orient itself towards p2
//just for debugging - to illustrate orientation
m.add(new THREE.Axes());
//visualize p1,p2 vectors
var PI2 = Math.PI * 2;
var program = function ( context ) {
context.beginPath();
context.arc( 0, 0, 1, 0, PI2, true );
context.closePath();
context.fill();
}
particleMaterial = new THREE.ParticleCanvasMaterial( { color: 0x990000, program: program } );
var pp1 = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0x990000, program: program } ) );
pp1.scale.multiplyScalar(10);
pp1.position.copy(p1);
scene.add( pp1 );
var pp2 = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0x009900, program: program } ) );
pp2.scale.multiplyScalar(10);
pp2.position.copy(p2);
scene.add( pp2 );
This should draw a cylinder that starts at p1, ends at p2 and is oriented towards it.
Offsetting might need some tweaking, but the geometry follows the vector direction pretty close.
There's also the longer version of manually computing the matrices, as opposed to relying on the lookAt() functionality:
plane.add(getCylinderBetweenPoints(p1,p2,new THREE.MeshLambertMaterial( { color: 0x009900, wireframe: true, shading: THREE.FlatShading } )));
function getCylinderBetweenPoints(point1,point2,material){
var HALF_PI = -Math.PI * .5;
var diff = new THREE.Vector3().sub(point1,point2);//delta vector
var halfLength = diff.length() * .5;
var c = new THREE.CylinderGeometry(10, 10, halfLength * 2, 12, 1, false );
var orientation = new THREE.Matrix4();//a new orientation matrix to offset pivot
var offsetRotation = new THREE.Matrix4();//a matrix to fix pivot rotation
var offsetPosition = new THREE.Matrix4();//a matrix to fix pivot position
orientation.lookAt(point1,point2,new THREE.Vector3(0,1,0));//look at destination
offsetRotation.setRotationX(HALF_PI);//rotate 90 degs on X
offsetPosition.setPosition(new THREE.Vector3(-point1.x,diff.length()*.5+point1.z,point1.y*.5));//move by pivot offset on Y
orientation.multiplySelf(offsetRotation);//combine orientation with rotation transformations
orientation.multiplySelf(offsetPosition);//combine orientation with position transformations
c.applyMatrix(orientation);//apply the final matrix
var m = new THREE.Mesh( c, material );
m.add(new THREE.Axes());
return m;
}
var PI2 = Math.PI * 2;
var program = function ( context ) {
context.beginPath();
context.arc( 0, 0, 1, 0, PI2, true );
context.closePath();
context.fill();
}
//visualize p1,p2 vectors
particleMaterial = new THREE.ParticleCanvasMaterial( { color: 0x990000, program: program } );
var pp1 = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0x990000, program: program } ) );
pp1.scale.multiplyScalar(10);
pp1.position.copy(p1);
plane.add( pp1 );
var pp2 = new THREE.Particle( new THREE.ParticleCanvasMaterial( { color: 0x009900, program: program } ) );
pp2.scale.multiplyScalar(10);
pp2.position.copy(p2);
plane.add( pp2 );
This looks like me more work than using quaternion, from what I see in you're code. If the setFromEuler does the magic for orientation, the mesh's geometry still might need to move (pivot from one end rather than centre)
HTH

Categories