 A Flash Developer Resource Site

1. ## 3D question

Hi,

I have a square setup, sitting in 3D space, I'm also applying some rotation to the square, so "viewpoint" is slightly rotated. Now what I want is for when I move over the 3d square for it to "come out" or move forward in the direction of its face. I tried just adding to the z coordinates of the 4 corner points of the square, but what I find is that it just moves the square away from whatever angle i'm looking at it. I thought maybe I need to give it a vector and then rotate that vector in the oposite direction to what the viewpoint angle is, but that doesn't seem to be working either, so any help appreciated.

regards
boombanguk  Reply With Quote

2. Hi
What you want to do is move your 3D square out along an axis of it's orientation , in your case this would be along the 3D squares (object space) z axis.

How you code this up depends on how you are representing and implementing your 3D squares orientation / rotation.  Reply With Quote

3. well this is basically the code im using to convert the 3d points to 2d, and at the same time rotate them

Code:
```	var pointIn2D = new Object();
var x = pointIn3D.xPos-cameraView.x;
var y = pointIn3D.yPos;
// no movement in y
var z = pointIn3D.zPos-cameraView.z;
var angle = Math.atan2(z, x);
pointIn3D.xPos = x;
pointIn3D.zPos = z;
var scaleRatio = focalLength/(focalLength+(pointIn3D.zPos));
pointIn2D.xPos = (pointIn3D.xPos)*scaleRatio;
pointIn2D.yPos = (pointIn3D.yPos)*scaleRatio;
// return the new 2D point
return pointIn2D;```
how would i implement what you said?  Reply With Quote

4. That code would seem to be for transforming your 3D points from World Space to View Space and then to 2D screen cords.

It seems that your 3D square is centered around the World Space origin and you are moving the Camera around? Is that what you actually want?  Reply With Quote

5. Ok I just thought of an easy way to solve your question.

Your 3D square is a plane in space and it has a vector pointing out from its face which is normal to the plane of the face. All you have to do is calculate this normal then move your points along the direction of this normal vector by some increment of your choice.

And here is a function which will do that.

Code:
```//just a simple vector object
function Vector3D(x,y,z){
this.x=x;
this.y=y;
this.z=z;
};
//arguments are Vector3D objects representing the x,y,z cordinates of your square in World Space, and the increment you would like them moved.
function movePointsAlongNormal(p0,p1,p2,p3,incr){
var ax,ay,az,bx,by,bz,nx,ny,nz,n;
var ax=p1.x-p0.x;
var ay=p1.y-p0.y;
var az=p1.z-p0.z;
var bx=p1.x-p2.x;
var by=p1.y-p2.y;
var bz=p1.z-p2.z;
var nx=(ay*bz)-(az*by);
var ny=(az*bx)-(ax*bz);
var nz=(ax*by)-(ay*bx);
var len=Math.sqrt(nx*nx+ny*ny+nz*nz);
var normal = new Vector3D(nx/len,ny/len,nz/len);
p0.x+=normal.x*incr;
p0.y+=normal.y*incr;
p0.z+=normal.z*incr;

p1.x+=normal.x*incr;
p1.y+=normal.y*incr;
p1.z+=normal.z*incr;

p2.x+=normal.x*incr;
p2.y+=normal.y*incr;
p2.z+=normal.z*incr;

p3.x+=normal.x*incr;
p3.y+=normal.y*incr;
p3.z+=normal.z*incr;
};

Vector3D.prototype.outPut=function(mesg){
trace(msg+" "+this.x+", "+this.y+", "+this.z);
};

// .................Below here is just a test example it can all be removed

//points for 3D square which is positioned at the World Space origin and a normal pointing down the World z axis.

var point0_In3D = new Vector3D(10,10,0);
var point1_In3D = new Vector3D(-10,10,0);
var point2_In3D = new Vector3D(-10,-10,0);
var point3_In3D = new Vector3D(10,-10,0);
//output original point position
point0_In3D.outPut("pnt0 before ");
point1_In3D.outPut("pnt1 before ");
point2_In3D.outPut("pnt2 before ");
point3_In3D.outPut("pnt3 before ");

//move points along normal by an increment of 10
movePointsAlongNormal(point0_In3D,point1_In3D,point2_In3D,point3_In3D,10);

//position of points after being moved along normal
//output original point position
point0_In3D.outPut("pnt0 after ");
point1_In3D.outPut("pnt1 after ");
point2_In3D.outPut("pnt2 after ");
point3_In3D.outPut("pnt3 after ");```
Use negative or positive increments to move forward or back.
How you use the function depends if you are updating your transforms in a continual loop or if your transforms are only event driven?  Reply With Quote

6. I'm using a loop.
well Originally I wanted a situation, where I could rotate/move the square in 3D space, AND apply my camera view on top of that, seems simple enough but I could never really get it to work. I looked into matrices but that didn't seem straightforward either, so i've got what i've ended up with thanks for the code, i'll give it a go.  Reply With Quote

7. have a look at this. it uses local to global to combine rotation/movement
http://users.nlc.net.au/oceana/tutor...erspective.htm  Reply With Quote

8. Hi Boombanguk,

Yes matrices can seem complex but they are not really that bad. Once explained in a way you can understand they are easy to use.

If you would like to have a full VR camera etc and you want to spend the time I can give you pointers / lessons and working code.

Let me know on that one.

Otherwise you can use the code I posted. You will most probably need some advice on pluging the code into yours.

How are you storing the data that makes up your 3D square? Is it all encapsulated into a single object? That would be the easy way ... but may not be the way you have things set-up?

-----------------------------------------------------------------------
The following is just an example of 3D object class, you do not need this to use the code I posted. That is just a simple example ... to give you some idea what you would be looking at learning about ... you should be able to tell if you want to go down that path ... towards full VR API as you initially wanted.

Code:
```//first just a simple 3d vector object to make the code easier to read
function Vector3D(x,y,z){
this.x=x;
this.y=y;
this.z=z;
};
Vector3D.prototype.set=function(x,y,z){
this.x=x;
this.y=y;
this.z=z;
};

//now the 3D object class
function Object3D(){
this.position=new Vector3D(0,0,0); //position in World Space
this.localPoints=new Array();         //object space points
this.worldPoints=new Array();        //world space points
this.screenPoints=new Array();      //screen space points
};

//initialize objects position, width and height
Object3D.prototype.Init=function(x,y,z,wide,heigh){
//set world position
this.position.set(posx,posy,posz);
//add points to object (a square) local object space
this.localPoints.push(new Vector3D(wide,heigh,0);
this.localPoints.push(new Vector3D(-wide,heigh,0);
this.localPoints.push(new Vector3D(-wide,heigh,0);
this.localPoints.push(new Vector3D(wide,-heigh,0);
//calculate object points positions in World space
this.WorldPoints.push(new Vector3D(wide   +posx,  heigh+posy, 0+posz);
this.WorldPoints.push(new Vector3D(-wide +posx,   heigh+posy, 0+posz);
this.WorldPoints.push(new Vector3D(-wide +posx, -heigh+posy, 0+posz);
this.WorldPoints.push(new Vector3D(wide  +posx,  -heigh+posy, 0+posz);
};

//here is a simple function which rotates the points around the objects center using matrix math.
Object3D.prototype.RotatePoints=function(rx,ry,rz){
//coefficients to build rotation matrix
var a = Math.cos(rx*(Math.PI/180));//x plane
var b = Math.sin(rx*(Math.PI/180));
var c = Math.cos(ry*(Math.PI/180));//y plane
var d = Math.sin(ry*(Math.PI/180));
var e = Math.cos(rz*(Math.PI/180));//z plane
var f = Math.sin(rz*(Math.PI/180));

//create 3x3 matrix from coefficients
// X axis
var mxx=(c*e);	var mxy=(b*d*e+a*f);	var mxz=(-a*d*e+b*f);
//Y axis
var myx=(-c*f);	var myy=(-b*d*f+a*e);	var myz=(a*d*f+b*e);
//Z axis
var mzx=d;	var mzy=(-b*c);	             var mzz=(a*c);

//rotate object around its center using matrix
var p,x,y,z;
for(i in this.localPoints){
p=this.localPoints[i];
x=p.x * mxx + p.y * mxy + p.z * mxz;
y=p.x * myx + p.y * myy + p.z * myz;
z=p.x * mzx + p.y * mzy + p.z * mzz;

//new rotated point positions
p.x=x;
p.y=y;
p.z=z;
}
};```

post back with any questions  Reply With Quote

9. thanks for that, its appreciated!

Quick first question. Why are you not using the Flash 8 matrix class?  Reply With Quote

10. ok more questions 1) So this rotates the object (square) on its own axis? so its spinning on the spot so to speak? its not rotating around the world o,o origin??

2) does this change the actual model (square) coordinates? because I've heard of something called destructive and non-destructive transformations, which are these? or does it depend on how its implemented?  Reply With Quote

11. Hi,
I don't tend to use a matrix class ... only when I really have to ... to keep things orderly ... or I am developing in a new area and doing lots of debugging. In general I prefer to handle the data directly. For 3D transforms you are usually just doing vector dot products and vector cross products and vector scaling, so a fully functional matrix class is overkill. I also find I gain a better understanding of code if the vector math is fully exposed ... there are lots of optimizations that can be missed if your data is wrapped in a class.

RotatePoints code would rotate the 3D square around it's local origin not the world origin ... yes so that it's spining on the spot.

In short yes it depends on how it is implemented and what if any data you cache between transforms that make for a destructive method. In general I have found the term to refer to a case where some data is not cached but overwritten each frame and recalculated.
ie you can often cache the World Space transform and avoid the Object Space to World Space transform by just combining the next transform with the previous World Space transform ... this would be non-destructive ... data wise. However doing this can lead to small errors in numerical precision to creep in and grow larger each frame until your 3D object has lost it's original shape. So the non destructive method can be faster but can cause problems that cause a geometric destruction ... so to speak.
Often a compromise is found and a Object Space to World Space transform is performed at a set frame interval in order to keep things in line. This is why it is common to look at the Object Space model data as an original copy from which you calculate the 3D objects current position and orientation.

I would suggest setting up a basic 3D Object class with data like.
Position - a 3 component vector
Orientation - a 3x3 matrix or quaternion prepresenting the objects current rotation
array of Object Space points - 3d objects points in Object Space
array of World Space points - 3d objects points in World Space
array of View Space points - optional 3d objects points in View Space
array of Screen Space points - 3d objects 2d screen cordinates

Remember that you may need to alter the code examples I posted to fit your situation ... I can help you do that when you have worked out which way you want to go. Think thrice, code once (well a good rule of thumb).  Reply With Quote

12. Hi,

I can get your example to rotate my square, but how would I implement a camera? is that what you mean by "view space" ? and would you have a seperate matrix for each set of points?  Reply With Quote

13. any help creating a camera, and then how that fits in with its own matrix and the other matrices would be much appreciated   Reply With Quote

14. Hi again,
I must ask at this point "how far do you want to go??". Is this just a quick project you want up and running or are you more interested in learning and implementing a more complete VR engine over a longer period of time?

I can explain how a Camera is set up and supply you with the code ... which ever way go want to go.

If it's something quick you want then my approach to it will be different than if it is a longer learning and coding experience you are interested in.

I have a pretty complete 6DOF VR API for Flash (that is robust and works well), with lighting, back-face culling, Camera frustrum culling, it is coupled to a physics engine with collision detection and response. So there is a lot you can learn ... if you wish.

Will await and see which route you would like to take.  Reply With Quote

15. Hi,

Thanks for the help!
I don't need an advanced camera system. I just a basic setup, where I can rotate my object on the x,y,z axis, and then be able to move a camera view around that object and rotate the camera as well. Hopefully all using a nice simple matrix system, that I can plug into my code   Reply With Quote

16. Hi,
That will make things easier.

I will put something together for you and advise how you can plug it into your code. You will have to give me a couple of days as tomorrow I will be busy with other commitments.

I will keep it as simple as possible, you can always extend it later.

I will also code up a basic mesh class, so that you can build simple polygon Mesh objects.  Reply With Quote

17. Originally Posted by shipstern
Hi,
That will make things easier.

I will put something together for you and advise how you can plug it into your code. You will have to give me a couple of days as tomorrow I will be busy with other commitments.

I will keep it as simple as possible, you can always extend it later.

I will also code up a basic mesh class, so that you can build simple polygon Mesh objects.

I'm happy to wait a few days, thanks for taking the trouble to help me out.
I really don't need a mesh made though, the project i'm creating relies just on a simple quad (square).  Reply With Quote  Reply With Quote

19. Originally Posted by shipstern
when I say quad, I literally mean 4 points, not 2 tri's which I know a quad is usually made up of! thanks again.  Reply With Quote

20. There is really no difference in the code if it is transforming 4 or 400 points, no more or less complex. In the end you can use it to transform as many or as few points/vertices as you wish.

Will most probably be able to post the code sometime tomorrow.  Reply With Quote

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•

 » Home » Movies » Tutorials » Submissions » Board » Links » Reviews » Feedback » Gallery » Fonts » The Lounge » Sound Loops » Sound FX » About FK » Sitemap 