Rotating an Object in world space #38
Replies: 3 comments 3 replies
-
After asking the question above, I came up with the following: class MyContainer3D extends PIXI3D.Container3D {
If you add the above container to a container and rotate the parent container or move it around, then after you are done with the container, you can use saveTransform to remember the transform the parent container had, then you are free to add it back to the main container, that the object was in originally. Example:
// add objects that you wish to rotate to this container, for instance a bunch of cubelets
|
Beta Was this translation helpful? Give feedback.
-
Nice that you found a solution! I guess one other way of doing it would be to have the mesh (piece) as a child of another container and rotate that container instead of the piece. All pieces should have their own container to rotate. Maybe something something like:
Then you rotate Container1, Container2 and Container3 to whatever you need, the pieces should not be rotated. Not sure if it's a better or worse solution though :) |
Beta Was this translation helpful? Give feedback.
-
I wanted to try this as well and came up with the following. It's not complete but should be easy to expand. The key is pretty much this part (where I first rotate and then apply world transform): let matrix = PIXI3D.Mat4.multiply(PIXI3D.Mat4.fromQuat(PIXI3D.Quat.fromEuler(0, 0, 45)),
p.worldTransform.toArray())
p.transform.setFromMatrix(new PIXI3D.TransformMatrix(matrix)) Here is the complete code (press a, s and d to rotate): const colorVert = `
attribute vec3 a_Position;
attribute vec3 a_Normal;
uniform mat4 u_World;
uniform mat4 u_ViewProjection;
varying vec3 v_Normal;
void main() {
gl_Position = u_ViewProjection * u_World * vec4(a_Position, 1.0);
v_Normal = a_Normal;
}`
const colorFrag = `
varying vec3 v_Normal;
void main() {
gl_FragColor = vec4(v_Normal * 0.5 + 0.5, 1.0);
}`
class ColorMaterial extends PIXI3D.Material {
constructor() {
super()
}
updateUniforms(mesh, shader) {
shader.uniforms.u_World = mesh.worldTransform.toArray()
shader.uniforms.u_ViewProjection = PIXI3D.Camera.main.viewProjection
}
createShader() {
let program = PIXI.Program.from(colorVert, colorFrag)
return new PIXI3D.MeshShader(program)
}
}
class Piece extends PIXI3D.Container3D {
constructor(x, y, z) {
super()
this.mesh = this.addChild(PIXI3D.Mesh3D.createCube(new ColorMaterial()))
this.mesh.position.set(x, y, z)
this.scale.set(0.3)
}
}
let app = new PIXI.Application({
backgroundColor: 0xdddddd, resizeTo: window, antialias: true
})
document.body.appendChild(app.view)
let control = new PIXI3D.CameraOrbitControl(app.view)
let pieces = []
for (let x = -1; x < 2; x++) {
for (let y = -1; y < 2; y++) {
for (let z = -1; z < 2; z++) {
pieces.push(app.stage.addChild(new Piece(x * 2.1, y * 2.1, z * 2.1)))
}
}
}
function getFrontPieces() {
return pieces.filter(p => p.mesh.worldTransform.position[2] > 0.5)
}
function getTopPieces() {
return pieces.filter(p => p.mesh.worldTransform.position[1] > 0.5)
}
function getRightPieces() {
return pieces.filter(p => p.mesh.worldTransform.position[0] > 0.5)
}
document.onkeypress = (evt) => {
if (evt.key === "a") {
getTopPieces().forEach(p => {
let matrix = PIXI3D.Mat4.multiply(PIXI3D.Mat4.fromQuat(PIXI3D.Quat.fromEuler(0, 45, 0)),
p.worldTransform.toArray())
p.transform.setFromMatrix(new PIXI3D.TransformMatrix(matrix))
})
}
if (evt.key === "s") {
getRightPieces().forEach(p => {
let matrix = PIXI3D.Mat4.multiply(PIXI3D.Mat4.fromQuat(PIXI3D.Quat.fromEuler(45, 0, 0)),
p.worldTransform.toArray())
p.transform.setFromMatrix(new PIXI3D.TransformMatrix(matrix))
})
}
if (evt.key === "d") {
getFrontPieces().forEach(p => {
let matrix = PIXI3D.Mat4.multiply(PIXI3D.Mat4.fromQuat(PIXI3D.Quat.fromEuler(0, 0, 45)),
p.worldTransform.toArray())
p.transform.setFromMatrix(new PIXI3D.TransformMatrix(matrix))
})
}
} |
Beta Was this translation helpful? Give feedback.
-
Is there a possible way to rotate an object in its world space instead of local space.
My scenario:
I'm building a rubiks cube,
I want to rotate a face, but by doing so I am changing the rotationQuaternion,
I can't simply create a container and add items into it, as the front face shares cubes with the side face, and will change.
What would be nice is to rotate a container containing objects, and then put them back into the world, but keep the rotation from the container once but into the main container.
I know PIXI only allows for one child to each parent, so an object can't share containers either.
I am a bit stumped here, is there a way to do this or wasn't PIXI built for this sort of thing.
Some pseudo code:
push objects to rotate into a container,
rotate the container
put the objects back into another container and keep the container rotations.
If I rotate individual cubes, then lets say I turn the right face then front face, the cube rotations from the right turn will now effect the z rotation on the front face.
I did manage to actually get it right by doing the following:
Rotate a face, at the end of the rotation, reset all cubes to their starting positions and rotations, and texture the cube using an internal data structure that has that information. That way on every turn, the rotations and translations of the previous cube are reset. So any new translations will be reset with a "new" cube everytime.
My question is this:
Is there a way to actual do this by rotating the cube in a world space, and not local space, so possibly moving the transform.up of an element, or above by creating a parent container and rotating that, or any other smart way of doing this?
For instance in UrhoSharp I was able to do this:
RotateAroundBy(duration, vector, degX, degY, degZ, TransformSpace.parent);
Beta Was this translation helpful? Give feedback.
All reactions