I want to make transforms around a pivot point using webgl. Inspired by Three.js and this comment
Create a object that will act as pivot:
mesh.position.y = 10;
var pivot = new THREE.Object3D(); pivot.add( mesh );
scene.add( pivot );
I am trying to set the pivot to some point and rotate the object. Here's my code to do these:
let transforms = {};
this.makeTransform = (name, transform) => {
transforms[name] = modelMatrix(transform);
};
const modelMatrix = transform => {
let matrix = transforms[transform.transform] || mat4.identity();
return mat4.transform(matrix, transform);
};
const mvpMatrix = modelMatrix => {
const { pos: camPos, target, up } = camera;
const { fov, aspect, near, far } = camera;
let camMatrix = mat4.lookAt(camPos, target, up);
let viewMatrix = mat4.inverse(camMatrix);
let projectionMatrix = mat4.perspective(fov, aspect, near, far);
let viewProjectionMatrix = mat4.multiply(projectionMatrix, viewMatrix);
return mat4.multiply(viewProjectionMatrix, modelMatrix);
};
this.drawMesh = (name, transform) => {
const uMatrix = mvpMatrix(modelMatrix(transform));
// set uMatrix as uniform and draw
}
Usage (render code):
r.makeTransform('root', {
translate: [100, 0, 0]
});
r.drawMesh('sample', {
transform: 'root',
translate: [0.0, 0.0, 2.0],
rotate: [0.0,
Math.PI,
0.0]
});
So I don't have a scene graph, but I make transform matrices and apply them to objects. Here sample
mesh is applied a root
transform. This translates the object on the x axis, and still rotates the object around it's origin.
But I can't rotate the object around a pivot point using the mentioned approach.
Based on gman answer this works :
r.makeTransform('root', {
translate: [0, 0, 0],
rotate: [0.0, u.PI, 0.0]
});
r.drawMesh('sample', {
transform: 'root',
translate: [100.0, 0.0, 0.0]
});
Because the vertices in geometries are defined so that the object center is at 0,0 origin.
like here
var x = ix * segmentWidth - widthHalf;
or here
for (let i = 0; i < vertices.length; i+=3) {
vertices[i] -= widthHalf;
vertices[i+1] -= heightHalf;
vertices[i+2] -= depthHalf;
}
A scene graph is just a way to represent a hierarchy of matrices. Here's a simple human scene graph
root
└─base
└─waist
├─chest
│ ├─neck
│ │ └─head
│ ├─left arm
│ │ └─left forearm
│ │ └─left hand
│ └─right arm
│ └─right forearm
│ └─right hand
├─left thigh
│ └─left leg
│ └─left foot
└─right thigh
└─right left
└─right foot
So to draw the right arm based on stereotypical webgl matrix math its
projectionMatrix * viewMatrix * rootMatrix * baseMatrix
* waistMatrix * chestMatrix * rightArmMatrix * rightForeArmMatrix
* rightHandMatrix
So looking at that you can translate any three.js scenegraph into plain matrix math. If it's
scene.add(pivot);
pivot.add(mesh);
Then your scene graph looks like
scene
└─pivot
└─mesh
so you need to end up with
projectionMatrix * viewMatrix * sceneMatrix * pivotMatrix * meshMatrix
Or to look at it another way
modelMatrix = sceneMatrix * pivotMatrix * meshMatrix
projectMatrix * viewMatrix * modelMatrix
The scenegraph itself just a way to make it easy it organize the matrices in a generic and flexible way rather than hard code all the math.
Note: sceneMatrix is usually the identity so you can leave it out but technically the scene in three.js is another node in the scene graph and so itself represents a matrix.
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.