-
about: getting the depth sort to work
Dear flashers,
I have studied the 3d articles from renderhjs, kirupa and some others (serveral times )
but i just cant get the depth sort to work proper
what i do now:
1 - create camera
2 - create models: only sets needed vars
3 - add onEnterFrame that loops all models and adds the faces to 1 global face array
4 - that faces array get sorted
5 - drawing the models
sample
source zipped
srcView
I hoped someone could help me with this and give a explanation what i did wrong (i know my problem is math.cos and math.sin because i just not fully understand the mechanics behind those functions what is my missing link in creating my own get2d)
Regards,
MasterX
PS: i do know that my code maybe isnt that fast or perfect but i am only focussing on the depth sorting ( i will optimize/use proper methods when i fully understands whats wrong with it now )
-
FINNALY got it "sorted" out (probably )
this post can be deleted
(big party over here)
Last edited by Master_X; 01-25-2009 at 12:22 PM.
-
got a swf demo of the fixed issue?
-
sure 
http://www.tiledbasedgames.com/3dtestdone/Main.html
PHP Code:
public function get2d(px:int, py:int, pz:int):Object{
py-= this.y; px-= this.x; pz-= this.z;
//top Z-Axis rotation
d = Math.sqrt(px*px+py*py);
a = Math.atan2(py, px) - this.pZ;
px= d * Math.cos(a);
py= d * Math.sin(a);
//side X-Axis rotation
d = Math.sqrt(py*py+pz*pz);
a = Math.atan2(pz,py) - this.pX;
py = -d * Math.sin(a);
pz = d * Math.cos(a)+0.022 *pz; //depth
return {x:px,y:py,z:-pz};
}
this.pZ is == pi/180 * rotationZ
this.pX is == pi/180 * rotationX
(because the render loop the rotationX/Z is always the same therefor i let that be pre calculated
PHP Code:
public function setPi():void{
this.pZ = this.rZ * p;
this.pX = this.rX * p;
}
and that function is called first before i loop my models and render them.
pz = d * Math.cos(a)+0.022 *pz; //depth
As you can see the depth is a little bit different as you sended me.
I also do a get2d calculation in the render function for every model itself
this.d_offset = this.cam.get2d(this.x, this.y, this.z).z*64;
this is added on the:
var zDepth:Number = get2d(avg_x, avg_y, avg_z).d + this.d_offset;
that way a face depth of model a never can slice a face of model b next to model a.
Because my work pc is very slow i also do:
if ((t[0].x>-320 || t[1].x>-320 || t[2].x>-320) && (t[0].x<320 || t[1].x<320 || t[2].x<320) &&
(t[0].y>-240 || t[1].y>-240 || t[2].y>-240) && (t[0].y<240 || t[1].y<240 || t[2].y<240)){
just before the Backface culling (saves me 2 till 4 frames a seconde)
the x-320, 320 and y - 240, 240 can be seen as the rect of the viewport (is checks if a face is in the viewport (if 1 of the vertex point of the face is within the viewport it must be visible if all 3 are not in the viewport the face can be invisible.
I hope i got the depth perfect now
yes the textures arent good that because i generate the vertex,faces,tvertex and tfaces array myself (only for testing atm) and not figured the tfaces array out yet (thats my next task ).
Regards,
MasterX
PS: i am very glad i found your articles if i made this amount of models in lets say papervision or sandy3d or another 3dengine it never would get the fps i got now
Last edited by Master_X; 01-26-2009 at 01:50 PM.
-
he he thanks for your input as well- seems you finished something I havent yet 
I will try out what you discovered in my stuff as well- see if I can tween more FPS out of it and fix some existing glitches.
if you need some help with 3d models or alike PM me- and I'll see how I can help you there.
-

(that nice i can teach the teacher some stuff )
here is my version of it:
PHP Code:
public function update():Array{
this.d_offset = this.cam.get2d(this.x, this.y, this.z).z*64;
i=0, j=0;
rdr = [];
length = this.fcs.length;
while (i<length){
t = [];
a_x = 0, a_y = 0, a_z = 0, j=0;
while (j<3){
v = vtx[fcs[i][j%3]];
t.push(this.cam.get2d(v.x+this.x, v.y+this.y, v.z+this.z));
a_x += v.x, a_y += v.y, a_z += v.z;
j++;
}
if ((t[0].x>-320 || t[1].x>-320 || t[2].x>-320) && (t[0].x<320 || t[1].x<320 || t[2].x<320) &&
(t[0].y>-240 || t[1].y>-240 || t[2].y>-240) && (t[0].y<240 || t[1].y<240 || t[2].y<240)){
if ((t[1].x-t[0].x)*(t[2].y-t[0].y)<(t[2].x-t[0].x)*(t[1].y-t[0].y)){
rdr.push({t:t, uv:tFp[i], d:this.cam.get2d(a_x, a_y, a_z).z + this.d_offset});
}
}
i++;
}
return rdr;
}
you probably already know where and what to do but maybe some others would also like to know.
my viewport is width 640 and height 480 (http://www.tiledbasedgames.com/3dtestdone/Main.html).
The 3d x=0, y=0, z=0 position is exactly in the center point of the viewport.
more simplyfied you get:
PHP Code:
var halfViewportWidth:int = (viewport.Width /2);//getting half the viewport width ( this case 320)
var halfViewportHeight:int = (viewport.Height/2); //getting half the viewport height (this case 240)
//since our 3d 0,0,0 point is in the center of the viewport you have to calculate the half size vars (uphere) upwards and downwards so minus the half and + the half
var xLeft:int = -halfViewportWidth; //(same as var xLeft:int = 0-halfViewportX)
var xRight:int = halfViewportWidth; //(same as var xRight:int = 0+halfViewportX)
var yTop:int = -halfViewportHeight; //(same as var yTop:int = 0-halfViewportY)
var yBottom:int = halfViewportHeight; //(same as var yBottom:int = 0+halfViewportY)
//do the check if all three traingle points are within the viewport
if ((tri[0].x>xLeft || tri[1].x>xLeft || tri[2].x>xLeft) &&
(tri[0].x<xRight || tri[1].x<xRight || tri[2].x<xRight) &&
(tri[0].y>yTop || tri[1].y>yTop || tri[2].y>yTop) &&
(tri[0].y<yBottom || tri[1].y<yBottom|| tri[2].y<yBottom)){
//yes it as atleast 1 point of the triangle within the viewport so needs to be visible
}
else{
//no all three points are out of the viewport so it not needs to be visible
}
this will do the same but now i use some easyer variable names that explain some more.
I make the xLeft, xRight, yTop and yDown static because the viewport sizes will stay the same.
PS:
maybe the half vars need to be tuned to make it just a little more smooth (not tested it yet). So then i would use -321, 321 and -241, 241
Last edited by Master_X; 01-26-2009 at 08:53 PM.
"I am the world and the world is I" Krishnamurti
-
some quick notes
is faster written this way
this
PHP Code:
py-= this.y; px-= this.x; pz-= this.z;
is faster using:
PHP Code:
py-= y; px-= x; pz-= z;
if its already a variable in your class you dont need the "this". You propably already know but each "." operation causes the FLashPlayer another look up and in a vital function that can slow down matters. Try to avoid all the "this" operators in the vital functions.
some quick comments on your approach so far:
I am quite impressed with you progressing so quick its really nice to see this.
as for
public function setPi():void{
this.pZ = this.rZ * p;
this.pX = this.rX * p;
}
I did pretty much the same but I removed it from the sample code I provided. The way I did it was using a setter in my class so something like:
PHP Code:
public function set rz(val:int):void{
pZ = rZ * p;
}
and the same for the x-axis. But since I hardly change the x-axis 1 line is saved compared to dooing booth at once.
As for PI, I have read somewhere that by reducing the digits after the one so
3.14159265...
using instead something like:
3.142
is of course less accurate but alot faster, try it out and see if you can squize out more fps
anyway will play with your results tomorrow in my engine - and see if it improves it as I hope it will
-
wow dude thats really nice, gonna try it directly.
about the: this. i always wondered if it would be faster without or with it (now i know)
PS: it did speed up +-1 fps (i gamble 0.7) (every frame counts )
Last edited by Master_X; 01-26-2009 at 09:29 PM.
"I am the world and the world is I" Krishnamurti
-
the way I do FPS counters is like this:
PHP Code:
private var fps_base:int = Stage.frameRate;
private var fps_ms:int = 0;
public function render():void{
/*
do complex 3d math stuff and heavy loops...
*/
var fps:Number = Number( (1000/fps_base) / (getTimer() - fps_ms) * fps_base).toFixed(2);
fps_ms = getTimer();//this is the dalay between each render operation
}
it should display you more accurate values like:
48.56 fps so you have 2 digits after the base, just output the local fps:Number value
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|