简体   繁体   中英

How do I rotate a mesh group about the axis of a random 3d object/mesh/3d line within the Three.js workspace?

I'm trying to learn more about three.js so I can perform testing on a simple mechanism. Ultimately the desired output would be board tilt (front view) to axle orientation (plan view) for different designs. (XY plot), but that's obviously step five or six.. I'm stuck on step one, trying to understand how to obtain an axis of rotation, represented by a small diameter cylinder.

Obviously this photo represents a fail. 总成旋转失败

  • I'm hoping to utilize the existing matrix tooling within Three.js to perform data charting / system analysis.
  • Its not clear on what the worldMatrix object within a mesh object really represents. I would think that contains location, orientation and scaling factors, but it not clear on how to extract that info for translation / 3d rotations of other components in the world space.
  • I'm guessing I'm better off making a copy of original component locations and matrix values, then working off of the copies. When you tilt left and back again, you don't end up in the original place.

The model represents a simple skateboard. I want to rotate the front truck hanger (which contains an axle and two wheels) about a tilted axis, according to a user selected slider element.

Sandbox here...

 var euler;
 const rotateMeshGroup =( meshGroup, rotationAxis, angleOfRotation) =>{
     euler = new THREE.Euler().setFromRotationMatrix(rotationAxis.matrixWorld);
     meshGroup.children.forEach(item => {
         item.rotateOnAxis(euler, THREE.MathUtils.degToRad(angleOfRotation));
     }) 
 }

I don't understand how one creates an axis of rotation. The 3D angle I understand, but what about distance from the axis? Is that a matrix cross product calculation (shortest distance to a 3D axis, with distance perpendicular to the axis? )

edit: Still trying to figure this one out. Been wading thru lots of console.logs and I don't see anything in the canned matrices that would work. I've converted the pivot axis from a small diameter cylinder mesh object into a simple line defined by two vector endpoints. I'm now thinking delta-x, delta-y, delta-z calculations (translate, rotation, translate back) within RotateMeshGroup function.

Any tips and hints here?

So, yeah, this was a work in progress. And I've now gone far beyond that. For me this was a learning exercise in using Three.js for engineering related analysis. I'd like to share some tips I've learned.

  1. I found this posting with answer from "Stranger in the Q" The code is of a rotating Solar System with Sun, Earth (with revolving moon and rocks) and Mars (with two other planets.) I went through this example very carefully, understanding, really understanding all that was going on. The program made clear how rotations are propagated through to children (Moon rotates around the Earth, while the Earth rotates around the Sun, etc...) The content was managed by a simple object external to the ThreeJS scene. The program uses some recursive functions to manage actions by children elements in the animation functioning. There are some updates required, eg the constructor for THREE.Object3d no longer takes names. The corrective action was to simple add a name value after object creation. When you name everything accurately, its much easier to understand the entire child hierarchy. Again this example was instrumental in helping me to understand some of this stuff.

  2. The other thing I found was a posting with an answer from BadAskTechie The response was simple, and directly to the point.

     //rotates a mesh's geometry about a specified axis and pivot //the axis is a normalized Vector3 const rotateAbout = (mesh, axis, axisPosition, angle) => { mesh.geometry.applyMatrix(new THREE.Matrix4().makeTranslation(mesh.position.x-axisPosition.x, mesh.position.y-axisPosition.y, mesh.position.z-axisPosition.z)); //translate geometry to axis location mesh.geometry.applyMatrix(new THREE.Matrix4().makeRotationAxis(axis, angle)); //rotate geometry about axis mesh.geometry.applyMatrix(new THREE.Matrix4().makeTranslation(axisPosition.x-mesh.position.x, axisPosition.y-mesh.position.y, axisPosition.z-mesh.position.z)); //translate geometry back to original location }
  3. One tip for complicated nested 3d meshes. Do all the geometry work, including component part orientation / translation / rotation, in the THREE.abcGeometry object stage. Don't create the meshs and then try to orient objects in the scene space. When you do the translations and rotations in geometry, everything lines up perfectly when it comes time for animation. Until I tried that nothing was making sense. The axis directions all seemed mixed up.

  4. There was one technique I found useful. I wanted to know where my elements were located in 3d space during rotation/animation functions. I could not figure out how to do that on 3d mesh objects. There are too many vertices to be useful. Instead I created a simple line object, and maneuver that along with the rest of the assembly during rotations. After an interim move, I could query the line by checking its two vertices, create a new 3d vector.normalize() and utilize that in future calculations. This seemed to work pretty well.

  5. The question I've asked above is really superseded by lots of progress on the whole skateboard truck model problem. Some of the code in the sandbox above is terrible. Please don't even waste time looking at it. Instead, I think what I'll do is open source the completed project, and list the github repo link and demo here, so others can get a glimpse on to my progress on same.

Perhaps that would be of use to others learning ThreeJS.

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