Showing posts with label OSD 600 0.3 Progress. Show all posts
Showing posts with label OSD 600 0.3 Progress. Show all posts

Wednesday, December 3, 2008

Solving other problems, help find hidden mistakes

After some more testing, I've realized that there were some major problems I need to fix before proceeding any further:
1) the center point (0, 0) on the canvas has some offset (about 3 pixels) in the browser
2) the (x, y) point of the mouse has not been converted from pixel to 3D coord

To quickly fix the first problem, I borrowed some code from a sample C3D demo:

function findPos(obj) {
var curleft = curtop = 0;
if (obj.offsetParent) {
do {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
} while (obj = obj.offsetParent);
return [curleft,curtop];
}
}

function getXandY( event )
{
var tempDiv = document.getElementsByTagName('canvas')[0];
var coords = findPos(tempDiv);
// determine the correct X, Y
var X = ( ( event.clientX - coords[0] ) + window.pageXOffset ) - (tempDiv.width / 2.0);
var Y = (tempDiv.height / 2.0) - ( event.clientY - ( coords[1] - window.pageYOffset ) );

return [X,Y];
}

As for the second problem, it took a little bit to figure out, but then I've came up with a temporary solution. I simply applied the same idea for getting the width of the far clipping plane, except here, I'm using the distance from position of the camera to the point it is looking at. And with that, I've calculated the ratio of the canvas to the actual space.

var camDist = Math.sqrt(Math.pow(camPos[0] - camLook[0], 2) + Math.pow(camPos[1] - camLook[1], 2) + Math.pow(camPos[2] - camLook[2], 2));
var midSpaceWidth = 2 * (camDist * Math.tan(degreesToRadians(theta));
var ratio = midSpaceWidth / tempDiv.width;
var tempX = ratio * currX;
var tempY = ratio * currY;

Now, this temporary solution only works when the object is at the look at position. So now I need to fix it so it'll work for objects at any position.

While coding this part, Andor and I also found a mistake that might have been causing a lot of problems from before. When we were calculating dz in the beginning, we did this:

var dz = dx / Math.tan(theta);

Mathematically, it seems right, but then we realize that the Math.tan needs to take a radian and not a degree number, so we quickly fixed that by changing it to:

var dz = dx / Math.tan(degreesToRadians(theta));

Luckily we saw this as we were making the pixel to 3D coord conversion, otherwise, we might have been stuck for a long time later on without realizing the problem has been there from the very beginning.

Tuesday, November 25, 2008

0.3 Progress

Today, I had another working session with Andor on the Picking project. With the help of the newly made C3D demo page, we managed to make a big step forward.

So now, we've changed the way we were converting the mouse window coord into 3D vector back into calculating with trig. Before the change, we were

1) Converting windows coord to NDC

var Cx = ((2 * currX) / ( tempDiv.width)) - 1 ;
var Cy = (2 * currY) / tempDiv.height;
var Cz = (2 * currZ) - 1;
var Cw = 1;


2) NDC to Viewspace

var viewCoord = multiplyMatrixByVector(projMatInv, new Array(currX, currY, currZ));
viewCoord[2] = -5;
viewCoord[3] = 6;

The multiplyMatrixByVector only calculates 3x3 matrix and a vector of 3 values. Therefore, the 3rd value will be calculated wrong and the 4th value will never be calculated. What we assumed here, is that the projMatInv never changes (since it's something we define), and with it, the 3rd and 4th value will always be calculated to be -5 and 6.

3) Viewspace to Model
modelMat x viewCoord
modelMat is a 4x4 matrix and viewCoord is a 4 value vector.


So what we did now instead, is back to using trig to calculate the distance from the camera position to the far clipping pan, and using that, we can calculate the dimension of it using ratio of the canvas dimension. And what we end up having in code now, is implementing Jeremy's idea of
1) Find distance to project plane

var dx = 0.5 * tempDiv.width; // tempDiv.width is canvas width
var theta = 0.5 * C3DL_FIELD_OF_VIEW; // angel of view in degrees
var dz = dx / Math.tan(theta); // distance

2) Make the vector of mouse picked point

var vPick = makeVector( currX, currY, dz );

3) Calculate the scale value to change the vector length to reach the far clipping plane and apply it to mouse vector

var scale = (C3DL_FAR_CLIPPING_PLANE - C3DL_NEAR_CLIPPING_PLANE) / dz;
vPick = multiplyVector(vPick, scale);

4) Orient the mouse vector to match our current camera view

viewMatrix = makePoseMatrix(scn.getCamera().getLeft(), scn.getCamera().getUp(), scn.getCamera().getDir(), scn.getCamera().getPosition());
vPick = multiplyMatrixByVector(viewMatrix, vPick);

Now, what we have here, is a vector of 3 value, which is the ending point of our mouse vector. In other words, this is the 3D coordinate of the point on our mouse vector intersecting the far clipping plane.

The next step now, is to try and make the actual line for this mouse vector, and do some initial intersection test for the line and the objects in the scene. After some time, Andor suggested that I try applying the object's trans matrix onto the mouse vector, and from that, we'd have both vector and object within the same space (model space). In that, we can then proceed to doing a bounding box check, and after that, I can do the actual object's intersection test.

What I need now, is
1) Mouse Vector Equation
2) Bounding Box/Object Face's Plane Equation
3) Equation for testing line/plane intersection

Onto testing and math review I go now...