简体   繁体   中英

Static Object in Scene - Three.js

I have two objects in my scene. I am using the

 <script src="js/controls/LeapTrackballControls.js"  ></script>

for moving the camera, so it feels like the objects is rotating according to the movement of my hand.

The problem is that the other object is also moving, and I want it to remain always in front of me. I mean, that even if the camera moves, the object always is in the same place inside the canvas/explorer.

Sorry if I'm not explaining myself properly.

Any help is appreciated.

EDIT:

var controls = new THREE.LeapTrackballControls( camera , controller );

So, I have a sphere in the middle of the scene. I use the LeapTrackball library to move the camera around the center of the scene. This makes the user feel like the sphere is rotating around his center.

model = new THREE.Mesh(modelGeo, modelMat);
model.geometry.dynamic = true;
model.position.set(0, 0, 0);
scene.add(model);

My problem is that I have another shape:

myMesh = new THREE.Mesh(circleGeometry, material);
myMesh.position.set(0, 0, 10);
scene.add(myMesh);

that is also affected by the rotation of the camera. What I want is to keep the 'fake rotation' of the sphere, while the other mesh stays in the middle of the screen (0,0,10).

Ok, so this is my camera object.

var camera = new THREE.PerspectiveCamera(55, window.innerWidth / window.innerHeight, 0.1, 5000);

And my render function, which is used for update the control/movement of the camera.

   function render() {
        controls.update();
        renderer.render(scene, camera);
        doMouse();
        if(useOrbitControls){
            orbitControls.update();
        }
    }

I'm using a Leap controller, and this is the function that builds it up:

function leapMotion() {
                var controllerOptions = {
                    enableGestures: true
                    , background: true
            , frameEventName: 'animationFrame'
                , };

[...]

    controller.on('frame', onFrame);

Basically, this means that the onFrame function is done everytime that it receives a frame (60 per second aprox.)

    function onFrame(frame){
[...]
        }

There is not much more, all the magic comes from the library that you can find here:

https://leapmotion.github.io/Leap-Three-Camera-Controls/

If you want an object -- such as crosshairs -- to be fixed in front of the camera, you can do so by adding the object as a child of the camera. Use a pattern like this one:

scene.add( camera ); // required when the camera has a child
camera.add( object );
object.position.set( 0, 0, - 100 ); // or whatever distance you want

three.js r.71

The simple way of doing this is making your object track the camera's position .

Tracking means that, at each camera update, you'll move both the camera and the object by the same amount , while keeping a fixed distance between them.

For this to work you need to set a fixed position at which your object will always be viewed, in your sample it should be (0, 0, 10).

var fixedPosition = new THREE.Vector3(0, 0, 10);

Then, in your render() function you need to update the position of the object after the camera was moved, but before you render everything.

function render() {
        controls.update();

        // let's update the object's position now!
        myMesh.position.sub(camera.position, fixedPosition);
        // now camera and mesh are at the same distance
        renderer.render(scene, camera);
        //...
    }

In this case a vector subtraction works fine, we basically take the camera's position, subtract our fixed amount (10 on the Z-axis) and you'll have that your object's position will always be positioned 10 units away from the camera on the Z-axis

In general, many of the operations you'll be doing involve 3D vectors and some math, so it's useful to understand how these operations (basic addition, subtraction, multiplication, etc.) affect what you see on screen.

If you have more doubts I suggest reading a bit about vector math, it's not too hard and you don't need to memorize formulas (Three.js implements all the math you need already), but knowing what these operations do can be incredibly useful.

Hope this helps someone who uses @react-three/fiber

import {useFrame, useThree} from "@react-three/fiber";

const { gl } = useThree();

const [ vrEnabled, setVREnabled ] = useState(false);

useFrame(({camera}) => {
    setVREnabled(gl.xr.isPresenting);

    if (vrEnabled) {
        camera.add(ref.current);
        ref.current.position.set( 18, 0, 0 );
    }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM