We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexSuggestions & BugsSoftware,  Documentation,  Website Suggestions › in addition to screenXYZ() also need...
Page Index Toggle Pages: 1
in addition to screenXYZ() also need... (Read 3432 times)
in addition to screenXYZ() also need...
Aug 9th, 2007, 1:06am
 
The screen?() functions are tremendously useful for getting screen coords, but they don't solve the problem of getting JUST the world coordinates from local coordinates given the current transform.  Nor is the modelview matrix particularly helpful since it starts as a camera matrix instead of identity.

What's missing is a set of routines that, if they existed, would perhaps be called something like worldX(), worldY() and worldZ().  For example:  float worldx = worldX(localx,localy,localz); et cetera.

That is, after establishing some complex series of translations, rotations and scalings how can you determine the resulting world coordinate that would be produced by a call such as point(x,y,z)?  Such that if that world coordinate were plotted in the *absence* of the transforms, you'd get the same screen coordinate as when the local coordinate were plotted *with* the transforms.

Alternatively, the modelview approach would be fine IF there were a way to completely remove any camera portions of the transform.  Does such a matrix exist in there somewhere?

Probably a poor description, how about code instead:

Quote:



size(200,200,P3D);
// coord as array of floats makes using the matrix mult easier
float [] local = {0,0,0};
float [] world = {0,0,0};
// plot a white point, given some transform
background(0);
camera();
rotateZ(PI/4);
translate(100,0,0);
stroke(255);
// transform in effect, plot *LOCAL* coordinate
point(local[0],local[1],local[2]);
// doing the math by hand suggests we just plotted at 100/sqrt(2),100/sqrt(2),0   or approx 70.7,70.7,0

//=============================================================  
// NOW, GIVEN THE EXISTING TRANSFORM, HOW DO WE ASK PROCESSING:
// "WHAT IS THE WORLD COORDINATE OF LOCAL COORDINATE 0,0,0?"
//=============================================================  
 
// one thought is to use the modelview matrix:
g.modelview.mult3(local, world);
println("world coords via modelview = " + world[0] + ", " + world[1] + ", " + world[2]);
// gives:  -29.289322, -29.289322, -173.20508
// err, NOPE, that doesn't work, and large -Z looks a lot like a camera value
// (and examining the source reveals why:  modelview starts as camera instead of identity)
 
// so we need a "clean" matrix to acccumulate JUST our local-to-world
// transform WITHOUT any of the camera stuff:
PMatrix mat = new PMatrix();
// mimic the above transform:
mat.reset();
mat.rotateZ(PI/4);
mat.translate(100,0,0);
 
// now let's see what that gives us:
mat.mult3(local, world);
println("world coords via our matrix = " + world[0] + ", " + world[1] + ", " + world[2]);
// gives:  70.71068, 70.71068, 0.0
// aha, YES! that's what we want

// so let's reset the camera and all transforms
// and replot over that white point with a transparent red,
// turning it pink as proof that we got the correct world coord
camera();
stroke(255,0,0,128);
// no transform in effect, plot *WORLD* coordinate
point(world[0], world[1], world[2]);




Any thoughts?
Re: in addition to screenXYZ() also need...
Reply #1 - Aug 15th, 2007, 9:23pm
 
(FYI) Maybe the "right"? way to do it Processing style is to use the recorder mechanism -- so when you're ready to start capturing transforms do something like:

PGraphics rec = createGraphics(1,1,P3D);
beginRecord(rec);
rec.modelview.reset(); // key point

Then do any series of translate/scale/rotate as you normally would.  To get world coordinates at any time do:

rec.modelview.mult3(local,world);

where local,world are float[3]'s as in prior msg.
Re: in addition to screenXYZ() also need...
Reply #2 - Aug 15th, 2007, 10:52pm
 
actually, modelX/Y/Z should be doing what you want--it's not named modelviewX/Y/Z after all Wink

but it seems as though there are problems in the current implementation:
http://dev.processing.org/bugs/show_bug.cgi?id=486

and it's just something i've not had a chance to straighten out (though it shouldn't be too ugly... probably a dumb mistake, like using the mv matrix and not removing the camera introduced around the time of beta when P3D was reworked).
Re: in addition to screenXYZ() also need...
Reply #3 - Aug 15th, 2007, 11:55pm
 
Thanks Fry, I had just figured that modelXYZ were intended for some "other" transform that I didn't understand, since they clearly weren't doing what I expected.  So, two things to suggest for the to-do-list:  modelXYZ() needs docs, and then work as doc'd.  Cheesy

Inserting into test code given above:

float mx = modelX(0,0,0);
float my = modelY(0,0,0);
float mz = modelZ(0,0,0);
println("world coords via modelXYZ = " + mx + ", " + my + ", " + mz);
// gives (incorrectly): -29.289322, 112.132034, 0.0
Re: in addition to screenXYZ() also need...
Reply #4 - Oct 30th, 2007, 5:52pm
 
With the recent succession of new Processing versions (thank you!), have modelX, modelY, modelZ been fortunate enough to get an update? Would be mighty happy to have a simple way to get 3D world coordinates!
Re: in addition to screenXYZ() also need...
Reply #5 - Nov 2nd, 2007, 8:16pm
 
Hay guys.

I've "hacked" modelX modelY and modelZ to work, out of necessity. Hopefully this will help fry or anyone else figure out what the bug inside processing is.

Code:

void setup(){
size(500,500,P3D);
}


float rx=0;
float ry=0;

float z = 200;
float boxSize = 15;

float m[] = {0,0,0};

void draw(){

background(255);


// get some rotations
rx = mouseY;
ry = mouseX;

noFill();
stroke(0,255,0);

// draw the box via translation
pushMatrix();
translate(width/2,height/2);
rotateY(radians(ry));
rotateX(radians(rx));
translate(0,0,z);
box(boxSize);

// WHILE we are translated, get modelX/Y/Z positions via this hack:
scale(0);
m[0] = modelX(0,0,0) + width/2;
m[1] = modelY(0,0,0) + height/2;
m[2] = modelZ(0,0,0) + (z + boxSize) * 2;
// m[2] offset is 430 ... double the z translation (200) plus the box size (15) multiplied by two

popMatrix();


// now that we have the world position, try directly drawing a box on it
stroke(255,0,0);
pushMatrix();
translate(m[0],m[1],m[2]); // <-- WORLD POSITION!
box(boxSize);
popMatrix();
}

Re: in addition to screenXYZ() also need...
Reply #6 - Nov 3rd, 2007, 4:45pm
 
thanks guys, just haven't had a time to get it straightened out yet. hopefully soon. will probably add the unprojectXYZ stuff as well at the same time.
Re: in addition to screenXYZ() also need...
Reply #7 - Nov 17th, 2007, 6:47pm
 
i'm trying to reproduce the world coordinate effect in a different context and can't seem to understand how you (mflux) got yours to work. can't seem to deduce the logic. which works great by the way.

after having done this

translate(width/2,height/2);
 rotateY(radians(ry));      
 rotateX(radians(rx));
 translate(0,0,z);  

and without leaving the pushmatrix you seem to bypass the rotations, to add just width/2 and height/2

m[0] = modelX(0,0,0) + width/2;
m[1] = modelY(0,0,0) + height/2;

and for z the mysterious (z + boxSize) * 2?

m[2] = modelZ(0,0,0) + (z + boxSize) * 2;  
 //  m[2] offset is 430 ... double the z translation (200) plus the box size (15) multiplied by two

if you have a few minutes could you explain the underlying logic?

thanks a bunch. this is the best effort to simulate world coordinates that i've seen.

jeff
Re: in addition to screenXYZ() also need...
Reply #8 - Nov 21st, 2007, 5:42pm
 
now fixed in rev 0135.
http://dev.processing.org/bugs/show_bug.cgi?id=486
Re: in addition to screenXYZ() also need...
Reply #9 - Nov 22nd, 2007, 1:03am
 
There was no logic behind it. It was seriously just trial and error until I got something to work. Which is often how I do things... lol!

Quote:
now fixed in rev 0135.
http://dev.processing.org/bugs/show_bug.cgi?id=486


Great news!!!
Page Index Toggle Pages: 1