dojo.gfx matrix transformation - matrix

Matrix transformations has got my head spinning. I've got a dojox.gfx.group which I want to be draggable with Mover and then be able to rotate it around a certain point on the surface. My basic code looks like this:
this.m = dojox.gfx.matrix,
.
.
.
updateMatrix: function(){
var mtx = this.group._getRealMatrix();
var trans_m = this.m.translate(mtx.dx, mtx.dy);
this.group.setTransform([this.m.rotateAt(this.rotation, 0, 0), trans_m]);
}
The rotation point is at (0,0) just to keep things simple. I don't seem to understand how the group is being rotated.
Any reference to simplistic tutorial on matrix transformations would also help. The ones I've checked out haven't help too much.

Try the official dojox.gfx matrix tutorial. See if the official documentation helps.

The official documentation is where my head started spinning. Been staring at that for quite a long time because I couldn't make out how to feed the new coordinates into upcoming matrix transformations.
I've finally managed to figure out the problem though. It was a matter of connecting a listener to when the Mover triggers onMoveStop:
dojo.connect(movable, "onMoveStop", map, "reposition");
I then get the new moved distances and feed them into any rotation or scaling matrix translations in my graphic class:
updateMatrix: function(){
//So far it is the group which is being rotated
if (this.group) {
if(!this.curr_matrix){
this.curr_matrix = this.initial_matrix;
}
this.group.setTransform([
this.m.rotateAt(this.rotation, this.stage_w_2, this.stage_h_2),
this.m.scaleAt(this.scaling, this.stage_w_2, this.stage_h_2),
this.curr_matrix
]);
//this.group.setTransform([
// this.m.rotateAt(this.rotation, mid_x, mid_y),
// this.m.scaleAt(this.scaling, mid_x, mid_y),
// this.initial_matrix]);
}
},
reposition: function(){
mtx = this.group._getRealMatrix();
this.curr_matrix = this.m.translate(mtx.dx, mtx.dy);
},
Life's dandy again. Thanks Eugene for the suggestions.

Related

Display Mesh On Top Of Another | Remove Overalapping | Render Order | Three.js

I have 2 obj meshes.
They both have some common areas but not completely.
I displayed them both by adding them to screen ..
Just like a mesh on top of another.
But the lower mesh overlaps the top mesh
But what I want to acheive is the lower mesh should always stay below without overlapping and giving the space to the entire top mesh.
I went through this fiddle..Fiddle with renderorder
And I tried something with this like..
var objLoader1 = new OBJLoader2();
objLoader1.load('assets/object1.obj', (root) => {
root.renderOrder = 0;
scene.add(root);
});
var objLoader2 = new OBJLoader2();
objLoader2.load('assets/object2.obj', (root) => {
root.renderOrder = 1;
scene.add(root);
});
But I don't know for what reason the overlap still stays ..
I tried...
var objLoader1 = new OBJLoader2();
objLoader1.load('assets/object1.obj', (root) => {
objLoader1.renderOrder = 0;
scene.add(root);
});
var objLoader2 = new OBJLoader2();
objLoader2.load('assets/object2.obj', (root) => {
objLoader2.renderOrder = 1;
scene.add(root);
});
Then I tried going through this Fiddle .. Another Fiddle
But when I run in I get only the lower or the upper mesh .
But I want to see both without any overlaps..
var layer1 = new Layer(camera);
composer.addPass(layer1.renderPass);
layer1.scene.add(new THREE.AmbientLight(0xFFFFFF));
var objLoader1 = new OBJLoader2();
objLoader1.load('assets/object1.obj', (root) => {
layer1.scene.add(root);
});
var layer2 = new Layer(camera);
composer.addPass(layer2.renderPass);
layer2.scene.add(new THREE.AmbientLight(0xFFFFFF));
var objLoader2 = new OBJLoader2();
objLoader2.load('assets/object2.obj', (root) => {
layer2.scene.add(root);
});
I made the material depthTest to False
But Nothing Helped..
Can anyone help me achieve what I wanted ..
If anyone couldn't figure what I mean by overlapping see the image below..
And Thanks to anyone who took time and effort to go through and help me...
You can use polygonOffset to achieve your goal, which modifies the depth value right before a fragment is written to help move polygons off of eachother without visually changing the position:
material.polygonOffset = true;
material.polygonOffsetUnit = 1;
material.polygonOffsetFactor = 1;
Here is a fiddle demonstrating the solution:
https://jsfiddle.net/5s8ey0ad/1/
Here is what the OpenGL Docs have to say about polygon offset:
When GL_POLYGON_OFFSET_FILL, GL_POLYGON_OFFSET_LINE, or GL_POLYGON_OFFSET_POINT is enabled, each fragment's depth value will be offset after it is interpolated from the depth values of the appropriate vertices. The value of the offset is factor×DZ+r×units, where DZ is a measurement of the change in depth relative to the screen area of the polygon, and r is the smallest value that is guaranteed to produce a resolvable offset for a given implementation. The offset is added before the depth test is performed and before the value is written into the depth buffer.
You're experiencing z-fighting, which is when two or more planes occupy the same space in the depthBuffer, so the renderer doesn't know which one to render on top of the other. Render order alone doesn't fix this because they're both still on the same plane, regardless of which one gets drawn first. You have a few options to resolve this:
Move one of the beams ever so slightly up in the y-axis. A tiny fraction would give one priority over the other, and this distance may not be noticeable to the eye.
I saw your fiddle, and you forgot to add depthTest: false to your material. However, this will cause issues when depth-testing the rest of the shape, since some white is on top of the red, but also some red is on top of the white. The approach in the fiddle works only when it's a simple plane, not more complex geometries.
You can use a boolean operation that removes one shape from the other, like CSG.
I think you'd save yourself a lot of headache by using approach #1.

Getting global normal from hitTest.face.normal

I am doing a hitTest to create a section plane on a face normal. To get the global normal I have to do some reworking of the hitTest.face.normal. It seems to almost work, but my result seems to be slightly off from the actual normal, so I am thinking I am doing something wrong:
const normalMatrix = new THREE.Matrix3().getNormalMatrix( this.hitTest.object.matrixWorld );
const normal = this.hitTest.face.normal.clone().applyMatrix3( normalMatrix )
this.SectionExtension.tool.setSectionPlane(normal, this.hitTest.point)
As seen on the picture, my ending cut plane is slightly off the actual plane
Can anyone see what might be off in that way of getting the plane, or do anyone have a better way of finding the global normal?
Thank you in advance!
Could you share more details on what the face normal should be? Here is the code snippet how the viewer's context menu Section Plane creates the section plane based on the face hit point. It might help.
const selected = viewer.getSelection();
const intersection = viewer.impl.hitTest(status.canvasX, status.canvasY, false, selected);
// Ensure that the selected object is the on that recieved the context click.
if (intersection && intersection.face && selected.indexOf(intersection.dbId) !== -1) {
sectionExtension.tool.setSectionPlane(section, intersection.face.normal, intersection.point);
}
If anyone should be interested, then i found a solution to my problem
For some reason, when running
const currentFragId = this.hitTest.fragId;
const renderProxy = this.viewer.impl.getRenderProxy(this.viewer.model,currentFragId);
Before using the normal helped me to get the correct normal. I do not use the 'renderProxy' for anything - but i assume that it helps the viewer in some way. Anyway - this works for me!

three.js Geometry.faceVertexUvs setup is confusing

I am working on implementing a custom model importer. The file contains all the necessary info (vertices, vertex normals, vertex uv coordinates, materials, etc.)
It's important to note that the file contains models with multiple materials.
The setup of the vertices is fairly straight forward and is working correctly.
The setup of the faces I'm not 100% sure about. I do the following:
meshDict[name].faces.push(
new THREE.Face3(parseInt(triangles[t]),
parseInt(triangles[t + 1]),
parseInt(triangles[t + 2]),
[normals[parseInt(triangles[t])],
normals[parseInt(triangles[t + 1])],
normals[parseInt(triangles[t + 2])]],
new THREE.Vector3(1, 1, 1), matIndex));
Here: t is the index iterator of the triangles array, normals is an array that holds the normal information of the vertices and matIndex is the material index of the face based on the sub-mesh number from the object file. This also seems to work correctly.
Now for the hard part. I searched all day for a clear explanation and/or good example of how to set-up the faceVertexUvs of a multi material mesh, but every second post I found shows a different method to set this up. After a lot of trial and error I got to this solution that works, but throws a LOT of warnings...
for (var f = 0; f < faces.length; f++)
{
if (currentMesh.faceVertexUvs[faces[f].materialIndex] == undefined)
{
currentMesh.faceVertexUvs[faces[f].materialIndex] = []
faceOffset = (faces[f].materialIndex == 0? 0 : 1) * f;
}
currentMesh.faceVertexUvs[faces[f].materialIndex].push(f);
currentMesh.faceVertexUvs[faces[f].materialIndex][f - faceOffset] = [];
currentMesh.faceVertexUvs[faces[f].materialIndex][f - faceOffset].push(uvs[faces[f].a]);
currentMesh.faceVertexUvs[faces[f].materialIndex][f - faceOffset].push(uvs[faces[f].b]);
currentMesh.faceVertexUvs[faces[f].materialIndex][f - faceOffset].push(uvs[faces[f].c]);
}
Here uvs is an array of Vector2 of the same length as the vertices array.
Basically I am doing:
faceVertexUvs[materialIndex][faceIndex][uvs[a], uvs[b], uvs[c]].
The number of material indexes is equal to the number of sub-meshes that the object has.
So this solution kinda works OK, but some of the textures are not looking correct (I suspect because the UV mapping of that area is not being set correctly), and I am getting a lot of warnings that say:
Important to note that all the models look OK in the exporting program so the issue is not from there.
Any ideas as to what I am doing wrong here?
So I think I finally managed to figure it out and I got it working correctly, and since the documentation is severely lacking in this area, and the examples are not quite clear I'll post my understanding of this topic here for anyone having the same issue.
So it goes like this:
Geometry.faveVertexUvs[UV LAYER][face index][uv[face.a], uv[face.b], uv[face.c]]
As far as I understand unless you have an AO (ambient occlusion) map, you only use UV LAYER 0.
Now, if you define a material index when setting up the faces of the geometry then each face will be rendered with the corresponding material, and there is no need to split the UVs into separate areas like I was doing in my question. So you only have to use:
Geometry.faces.push(new THREE.Face3(v0, v1, v2, [n0, n1, n2], vertexColor, materialIndex));

Outline object (normal scale + stencil mask) three.js

For some time, I've been trying to figure out how to do an object selection outline in my game. (So the player can see the object over everything else, on mouse-over)
This is how the result should look:
The solution I would like to use goes like this:
Layer 1: Draw model in regular shading.
Layer 2: Draw a copy in red color, scaled along normals using vertex shader.
Mask: Draw a black/white flat color of the model to use it as a stencil mask for the second layer, to hide insides and show layer 1.
And here comes the problem. I can't really find any good learning materials about masks. Can I subtract the insides from the outline shape? What am I doing wrong?
I can't figure out how to stack my render passes to make the mask work. :(
Here's a jsfiddle demo
renderTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, renderTargetParameters)
composer = new THREE.EffectComposer(renderer, renderTarget)
// composer = new THREE.EffectComposer(renderer)
normal = new THREE.RenderPass(scene, camera)
outline = new THREE.RenderPass(outScene, camera)
mask = new THREE.MaskPass(maskScene, camera)
// mask.inverse = true
clearMask = new THREE.ClearMaskPass
copyPass = new THREE.ShaderPass(THREE.CopyShader)
copyPass.renderToScreen = true
composer.addPass(normal)
composer.addPass(outline)
composer.addPass(mask)
composer.addPass(clearMask)
composer.addPass(copyPass)
Also I have no idea whether to use render target or renderer for the source of the composer. :( Should I have the first pass in the composer at all? Why do I need the copy pass? So many questions, I know. But there are just not enough resources to learn from, I've been googling for days.
Thanks for any advice!
Here's a js fiddle with working solution. You're welcome. :)
http://jsfiddle.net/Eskel/g593q/6/
Update with only two render passes (credit to WestLangley):
http://jsfiddle.net/Eskel/g593q/9/
The pieces missing were these:
composer.renderTarget1.stencilBuffer = true
composer.renderTarget2.stencilBuffer = true
outline.clear = false
Now I think I've found a bit simpler solution, from the THREEx library. It pre-scales the mesh so you dont need a realtime shader for it.
http://jeromeetienne.github.io/threex.geometricglow/examples/geometricglowmesh.html

camera movement trajectory three.js

I think this picture better explains my problem: http://i48.tinypic.com/wvrbcy.png
On this picture the camera is moving along the ellipse. The code I have for this trajectory is:
var r = 0;
function render() {
cameraMain.rotation.y+=0.003;
cameraMain.position.x = Math.sin(r*0.1)*500;
cameraMain.position.z = Math.cos(r*0.1)*1000;
r+=Math.PI/180*2;
}
But that's not what I need. I want my camera to move in a kinda star trajectory, so that it'll have kinda 'zoom in' / 'zoom out' effect. How can I accomplish this?
You want to google "parametric equation" for "astroid", or "deltoid curve", or "superellipse".
Here are some links where you can get the kinds of parametric equations you are looking for:
Astroid: http://en.wikipedia.org/wiki/Astroid
Deltoid Curve: http://en.wikipedia.org/wiki/Deltoid_curve

Resources