1

I'm using Physijs script for physics like gravitation. I want to move objects in my scene with Raycaster from THREE.js script. My problem is that Raycaster only move objects (simple box) declared like:

var box = new Physijs.Mesh(cubeGeomtery.clone(), createMaterial);

But here physics does not work. It only works if I declare it like:

var create = new Physijs.BoxMesh(cubeGeomtery.clone(), createMaterial);

But here Raycaster / moving does not work.

The difference between these two is that in the first it's just Mesh and in the second it's BoxMesh.

Does anyone know why this doesn't work? I need BoxMesh in order to use gravity and other physics.

Code to add cube

function addCube()
        {
            controls.enable = false;
            var cubeGeomtery = new THREE.CubeGeometry(85, 85, 85);
            var createTexture = new THREE.ImageUtils.loadTexture("images/rocks.jpg");
            var createMaterial = new THREE.MeshBasicMaterial({ map: createTexture });
            var box = new Physijs.BoxMesh(cubeGeomtery.clone(), createMaterial);
            box.castShadow = true;
            box.receiveShadow = true;
            box.position.set(0, 300, 0);
            objects.push(box);
            scene.add(box);
        }
Rok
  • 133
  • 14
  • Is `cubeGeomtery` a typo? Seems like it should say `cubeGeometry`. – user513951 Jan 02 '16 at 19:17
  • This is my cubeGeomtery `var cubeGeomtery = new THREE.CubeGeometry(85, 85, 85);` – Rok Jan 02 '16 at 19:27
  • I can't find `Physijs.Mesh` in the documentation at https://github.com/chandlerprall/Physijs/wiki/Basic-Shapes. Can you post more of your code? – user513951 Jan 02 '16 at 19:31
  • Well looks like `Mesh` belongs to THREE.js. If i create `var create = new THREE.Mesh(cubeGeomtery.clone(), new THREE.MeshLambertMaterial({ color: 0x0000ff }));` Moving works just fine. But if I create object with code above (`new Physijs.BoxMesh`) it does not work – Rok Jan 02 '16 at 19:36

1 Answers1

0

Explanation

In Physijs, all primitive shapes (such as the Physijs.BoxMesh) inherit from Physijs.Mesh, which in turn inherits from THREE.Mesh. In the Physijs.Mesh constructor, there is a small internal object: the ._physijs field. And, in that object, there is... a shape type declaration, set to null by default. That field must be re-assigned by one of its children. If not, when the shape is passed to the scene, the Physijs worker script won't know what kind of shape to generate and simply abort. Since the Physijs.Scene inherits from the THREE.Scene, the scene keeps a reference of the mesh internally like it should, which means that all methods from THREE.js will work (raycasting, for instance). However, it is never registered as a physical object because it has no type!

Now, when you are trying to move the Physijs.BoxMesh directly with its position and rotation fields, it is immediately overridden by the physics updates, which started with the .simulate method in your scene object. When called, it delegates to the worker to compute new positions and rotations that correspond to the physics configurations in your scene. Once it's finished, the new values are transferred back to the main thread and updated automatically so that you don't have to do anything. This can be a problem in some cases (like this one!). Fortunately, the developer included 2 special fields in Physijs.Mesh: the .__dirtyPosition and .__dirtyRotation flags. Here's how you use them:

// Place box already in scene somewhere else
box.position.set(10, 10, 10);

// Set .__dirtyPosition to true to override physics update
box.__dirtyPosition = true;

// Rotate box ourselves
box.rotation.set(0, Math.PI, 0);
box.__dirtyRotation = true;

The flags get reset to false after updating the scene again via the .simulate method.

Conclusion

It is basically useless to create a Physijs.Mesh yourself, use one of the primitives provided instead. It is just a wrapper for THREE.Mesh for Physijs and has no physical properties until modified properly by one of its children.

Also, when using a Physijs mesh, always set either the .__dirtyPosition or the .__dirtyRotation property in the object to directly modify position or rotation, respectively. Take a look in the above code snippet and here.

Community
  • 1
  • 1