I'm trying to animate the lookAt method of an Object3D to lookAt a target Vector3. My Tween function traces floating points as per the incrementing scalarMultiplyVal (0.0 - 1.0), but no matter what I try the Object3D is already looking at the target before the tween starts. Very odd.
TweenMax.to( this, 5, {scalarMultiplyVal:1, onUpdate:function(){
let targetVector = new THREE.Vector3( target.position.x, target.position.y, target.position.z ).multiplyScalar( scalarMultiplyVal );
console.log( targetVector ) // logs "animating" x,y,z values as expected
displayObject.lookAt( targetVector ); // does not animate. Already fulling looking at target.position ( scalarMultiplyVal = 1.0 )
}});
Essentially I'm trying to have my Object3D animate/turn to look at a new vector3 periodically, but instead the Object3D is already fully looking at the target.position, and disregarding the vector multiplication. Very odd. Any advice will be a great help!
Instead of performing an animation with Object3D.lookAt() I highly recommend to use Quaternion.rotateTowards(). The method is based on Unity's Quaternion.RotateTowards. It internally performs a slerp which is ideal for your use case. The following example demonstrate the usage of Quaternion.rotateTowards().
https://threejs.org/examples/webgl_math_orientation_transform
three.js R104
Related
I have a complex object, i.e. a box, and I would like to cut it dynamically. This jsFiddle is a very simple example:jsFiddle
Very simple plane
var plane = new THREE.Mesh( geometry, material3 );
plane.rotation.x =1.3; // -Math.PI / 2;
gui.add(plane.rotation, "x", 0.1, Math.PI / 2).name("angle");
gui.add(plane.position, "y", -1, 1).name("h");
scene.add( plane );
I would like to remove from my object the upper part. Just like to cut off a piece from an apple using a knife.
The plane is the knife: In my example, you can play with 2 controls to move the plane up and down or change the angle.
Can you help me to hide the removed part from the object?
You've got two options:
You could use clipping as WestLangley mentioned above.
Clipping does not modify the vertex geometry, it's only visual.
Is non-destructive, so it's good for animating or making constant updates.
Clipping is mostly done with a few planes instead of complex geometry.
You could use a boolean operation with Constructive Solid Geometry.
Boolean does affect the vertex geometry, which can be exported.
Operation is "destructive", so you can't make updates once it's done.
Boolean can be performed with complex geometries, as long as they're "manifold".
Boolean operations require both geometries to be manifold geometries in order to work. This means both meshes have to be closed, without open faces. You cannot use infinitely thin planes, so the example in your JSFiddle wouldn't work. You would need to give each side a little bit of thickness, like using a box with a width of 0.0001 instead of a plane.
In Three.js, I have a 3d object where I am using local clipping planes to only render a part of the object.
However, since 3d objects are "hollow" (meaning only the outer surface is rendered), when we clip anything off that surface we can "see into" the object. Here's an example of what I mean, clipping a corner off a cube. Notice how we can see the backside of the opposite corner.
I would like to give the appearance of the object being solid. Based on this issue, it seems that the best way to accomplish this is to create a surface over the clipped region, thus capping the hole and making the object appear like it isn't hollow.
My question is, how do I know where to build this surface? Does Three.js provide a way to get a list of vertices that intersect between a plane and any arbitrary surface? If not, how might I approach this problem myself?
I found this question, but the author didn't describe how they solved the problem I am having here.
You want to render a clipped surface as if it were a solid -- i.e., not hollow.
You can achieve that effect with MeshPhongMaterial -- or any three.js material for that matter -- with a simple hack to the material shader.
material.onBeforeCompile = function( shader ) {
shader.fragmentShader = shader.fragmentShader.replace(
'#include <output_fragment>',
`
vec3 backfaceColor = vec3( 0.4, 0.4, 0.4 );
gl_FragColor = ( gl_FrontFacing ) ? vec4( outgoingLight, diffuseColor.a ) : vec4( backfaceColor, opacity );
`
)
};
This should look pretty good. It will require material.side = THREE.DoubleSide;
Alternatively, see https://threejs.org/examples/webgl_clipping_stencil.html.
three.js r.148
I made a THREE.SectionHelper class which could be interesting if you want to set a different material/color for the inside of the mesh that you are clipping. Check a demo in this fiddle.
var sectionHelper = new THREE.SectionHelper( mesh, 0xffffff );
scene.add(sectionHelper);
For each mesh (THREE.Object3D) Three.js provide a very handy properties - boundingSphere and boundingSphere that have intersectsSphere and isIntersectionBox methods.
With all this I thought I can use it for simple collision detection but when I try it appears that collision happens all the time because (I tried boundingSphere) boundingSphere.center is always in (0, 0, 0); So If I want to check collisions between 2 meshes I should for each object - clone boundingSphere object and then get it world coordinates and only then to use intersectsSphere.
something like this:
var bs = component.object.geometry.boundingSphere.clone();
bs.center.setFromMatrixPosition(component.object.matrixWorld);
...
if (_bs.intersectsSphere(bs)){
is this how it suppose to be used or am I missing something and there are more convenient way of doing collisions detection based on boundingBox/boundingSphere?
If you want to do collision detection with bounding boxes you need the boxes in the world coordinate system. The bounding volumes in the intersectsSphere and isIntersectionBox properties of the mesh are in the local coordinate system of the object.
You can do like you did: clone the volumes and move them to the correct position in the world coordinate system, that is a good solution.
Otherwise you can also set a new box from your meshes and do collision using those boxes. Let's say you have a THREE.Mesh called mesh then you can do:
sphere = new THREE.Sphere.setFromPoints( mesh.vertices );
box = new THREE.Box3.setFromObject( mesh );
A little tip. During development it can be nice to see the bounding boxes in your scene, for this you can use the THREE.BoundingBoxHelper:
var helper = new THREE.BoundingBoxHelper( mesh );
scene.add( helper );
I'm struggling to explain my problem, so please bear with me.
Is there a recommended way to re-apply the same transformations to an object in it's original shape for every frame, so that one can easily see the differences as the transforms changes the original object. In the pseudocode below, there is an "original object". In each frame, we apply the current transforms to the original object so we can see the differences.
UI Slider: Scale
UI Slider: Rotate
UI Slider: Position
For each frame {
Original Object -> ApplyCurrentScale -> ApplyCurrentRotate -> ApplyCurrentPosition
Render New Object
}
This way, as you change the transforms, in real time, you can watch the effect. I hope this makes sense.
Here is the pattern to follow, after you extract the parameters from the sliders:
object.scale.set( s, s, s );
object.setRotationFromAxisAngle( axis, angle ); // r.59
object.position.set( x, y, z );
renderer.render( scene, camera );
Another way to set the rotation is:
object.rotation.y = angle;
three.js r.59
I'm using THREE API in order to realize some animations in my app. Now i have a real problem : i'd like making spherical rotation around a specific point. The "rotate" method included in mesh objects allow me to make them, but the center of the rotation is (by default i guess) the center of the mesh.
Then, i only rotate my objects around themself...
I have already found some examples, but they don't solve my problem. I tried to create objects 3D parents like groups, and tried to make the rotation around this groups after having translated them, but this still does not work...
Can you please give me a hand about that ?
I'm so sorry, i found my problem... Making a jsfiddle made me realize i forgot to instanciate my parent as " a new Object 3D() ", that was why i didn't see any objects in my scene when i used animation on my parent... i give you a short part of my code anyway dedicated to interested people finding any help :
// mesh
mesh = new THREE.Mesh( geometry, material );
parent = new THREE.Object3D();
parent.add(mesh);
// if i want my rotation point situated at (300;0;0)
parent.position.set(300,0,0);
mesh.position.set(-300, 0, 0);
scene.add(parent);
http://jsfiddle.net/KqTg8/6/
Thank you