Code archives/3D Graphics - Misc/Alpha Zorder

This code has been declared by its author to be Public Domain code.

Download source code

Alpha Zorder by Beaker
(Posted 23 years ago)
Unlike normal and masked ones, Blitz doesn't sort alpha'd triangles, which leads
to far away objects appearing in front of near ones. 'Alpha Zorder' rectifies this
by sorting triangles, but only when needed. This makes it incredibly fast.

It's great for large numbers of trees and grass that contain some alpha mesh/textures.

Setup is slow at first, but it is possible to save the sorted data (code not included), so it is only calculated once.

There is a demo of the system here:
http://www.blitzbasic.com/codearcs/codearcs.php?code=807

One day I hope that programs like the excellent Gile[s] will calculate the
data when you render lightmaps etc. and save it to the exported file.
; code by Beaker 2002 - please credit prominently (or arrange otherwise)



Function setup_example(mesh)
	zo.zorder = Zorderize(mesh)
End Function

Function mainloop_example(cam)
	For zo.zorder = Each zorder
		SortAlpha(zo,cam)
	Next
End Function



Type zorder
	Field hiddenmesh
	Field hiddensurf
	Field screenmesh
	Field screensurf
	Field x,y,z		;banks: size = tricnt * 2bytes(short)
	Field tricnt	;counttriangles(surf)-1
	Field incy		;use the y axis
End Type


Function Zorderize.zorder(mesh, incy = False)
	zo.zorder = New zorder
	zo\hiddenmesh = mesh
	zo\incy = incy

	zo\hiddensurf = GetSurface(zo\hiddenmesh,1)

	zo\tricnt = CountTriangles(zo\hiddensurf)-1
	zo\x = CreateBank(zo\tricnt*2+8)
	DebugLog BankSize(zo\x)
	If incy
		zo\y = CreateBank(zo\tricnt*2+8)
	EndIf
	zo\z = CreateBank(zo\tricnt*2+8)

	For f = 0 To zo\tricnt
		PokeShort zo\x, f*2, f
		If incy
			PokeShort zo\y, f*2, f
		EndIf
		PokeShort zo\z, f*2, f
	Next

	zo\screenmesh = CopyMesh(zo\hiddenmesh)
;	zo\screenmesh = CopyMesh(zo\hiddenmesh,getparent(zo\hiddenmesh))
	HideEntity zo\hiddenmesh
;	EntityFX zo\screenmesh,16

	zo\screensurf = GetSurface(zo\screenmesh,1)

	surf = zo\hiddensurf	;GetSurface(fullmesh,1)
	If Not surf Then RuntimeError "No surface found"
	ordered = False
	While ordered = False
		ordered = True
		For f = 1 To zo\tricnt
	;		If f > 0
				v0 = TriangleVertex ( surf,PeekShort(zo\x,f*2),0 )
				v1 = TriangleVertex ( surf,PeekShort(zo\x,f*2),1 )
				v2 = TriangleVertex ( surf,PeekShort(zo\x,f*2),2 )
				medx# = (VertexX(surf,v0)+VertexX(surf,v1)+VertexX(surf,v2)) / 3.0

				v0b = TriangleVertex ( surf,PeekShort(zo\x,(f-1)*2),0 )
				v1b = TriangleVertex ( surf,PeekShort(zo\x,(f-1)*2),1 )
				v2b = TriangleVertex ( surf,PeekShort(zo\x,(f-1)*2),2 )
				medxb# = (VertexX(surf,v0b)+VertexX(surf,v1b)+VertexX(surf,v2b)) / 3.0

				If (medx) > (medxb)
					temp = PeekShort(zo\x,f*2)
					PokeShort zo\x,f*2, PeekShort(zo\x,(f-1)*2)
					PokeShort zo\x, (f-1)*2, temp
					ordered = False
				EndIf


				v0 = TriangleVertex ( surf,PeekShort(zo\z,f*2),0 )
				v1 = TriangleVertex ( surf,PeekShort(zo\z,f*2),1 )
				v2 = TriangleVertex ( surf,PeekShort(zo\z,f*2),2 )

				medz# = (VertexZ(surf,v0)+VertexZ(surf,v1)+VertexZ(surf,v2)) / 3.0

				v0b = TriangleVertex ( surf,PeekShort(zo\z,(f-1)*2),0 )
				v1b = TriangleVertex ( surf,PeekShort(zo\z,(f-1)*2),1 )
				v2b = TriangleVertex ( surf,PeekShort(zo\z,(f-1)*2),2 )
				medzb# = (VertexZ(surf,v0b)+VertexZ(surf,v1b)+VertexZ(surf,v2b)) / 3.0

				If (medz) > (medzb)
					temp = PeekShort(zo\z,f*2)
					PokeShort zo\z,f*2, PeekShort(zo\z,(f-1)*2)
					PokeShort zo\z,(f-1)*2, temp
					ordered = False
				EndIf
	;		EndIf
		Next

		If incy
			For f = 1 To zo\tricnt
				v0 = TriangleVertex ( surf,PeekShort(zo\y,f*2),0 )
				v1 = TriangleVertex ( surf,PeekShort(zo\y,f*2),1 )
				v2 = TriangleVertex ( surf,PeekShort(zo\y,f*2),2 )
				medy# = (VertexX(surf,v0)+VertexX(surf,v1)+VertexX(surf,v2)) / 3.0

				v0b = TriangleVertex ( surf,PeekShort(zo\y,(f-1)*2),0 )
				v1b = TriangleVertex ( surf,PeekShort(zo\y,(f-1)*2),1 )
				v2b = TriangleVertex ( surf,PeekShort(zo\y,(f-1)*2),2 )
				medyb# = (VertexX(surf,v0b)+VertexX(surf,v1b)+VertexX(surf,v2b)) / 3.0

				If (medy) > (medyb)
					temp = PeekShort(zo\y,f*2)
					PokeShort zo\y,f*2, PeekShort(zo\y,(f-1)*2)
					PokeShort zo\y, (f-1)*2, temp
					ordered = False
				EndIf
			Next
		EndIf

		If KeyDown(1) Then End
	Wend

	Return zo
End Function


Function SortAlpha(zo.zorder,cam)
	Local origsurf = zo\hiddensurf
	Local newsurf = zo\screensurf
	Local xf,yf,zf,f
	TFormVector 0,0,1, cam,0
	If (Abs(TFormedX()) > Abs(TFormedZ())) And (Abs(TFormedX()) > Abs(TFormedY()))
		If prev <> 1
			prev = 1
			ClearSurface newsurf,0,1
			If TFormedX() > 0
				For f = 0 To zo\tricnt
					xf = PeekShort(zo\x,f*2)
					AddTriangle ( newsurf,TriangleVertex ( origsurf,xf,0 ),TriangleVertex ( origsurf,xf,1 ),TriangleVertex ( origsurf,xf,2 ) )
				Next
			Else
				For f = zo\tricnt To 0 Step -1
					xf = PeekShort(zo\x,f*2)
					AddTriangle ( newsurf,TriangleVertex ( origsurf,xf,0 ),TriangleVertex ( origsurf,xf,1 ),TriangleVertex ( origsurf,xf,2 ) )
				Next
			EndIf
		EndIf
	Else
		If (Abs(TFormedY()) > Abs(TFormedZ()))
			If (prev <> 2) And zo\incy
				prev = 2
				ClearSurface newsurf,0,1
				If TFormedY() > 0
					For f = 0 To zo\tricnt
						yf = PeekShort(zo\y,f*2)
						AddTriangle ( newsurf,TriangleVertex ( origsurf,yf,0 ),TriangleVertex ( origsurf,yf,1 ),TriangleVertex ( origsurf,yf,2 ) )
					Next
				Else
					For f = zo\tricnt To 0 Step -1
						yf = PeekShort(zo\y,f*2)
						AddTriangle ( newsurf,TriangleVertex ( origsurf,yf,0 ),TriangleVertex ( origsurf,yf,1 ),TriangleVertex ( origsurf,yf,2 ) )
					Next
				EndIf
			EndIf
		Else
			If prev <> 3
				prev = 3
				ClearSurface newsurf,0,1
				If TFormedZ() > 0
					For f = 0 To zo\tricnt
						zf = PeekShort(zo\z,f*2)
						AddTriangle ( newsurf,TriangleVertex ( origsurf,zf,0 ),TriangleVertex ( origsurf,zf,1 ),TriangleVertex ( origsurf,zf,2 ) )
					Next
				Else
					For f = zo\tricnt To 0 Step - 1
						zf = PeekShort(zo\z,f*2)
						AddTriangle ( newsurf,TriangleVertex ( origsurf,zf,0 ),TriangleVertex ( origsurf,zf,1 ),TriangleVertex ( origsurf,zf,2 ) )
					Next
				EndIf
			EndIf
		EndIf
	EndIf
End Function

Function FreeZorder()
	For zo.zorder = Each zorder
		FreeEntity zo\screenmesh 
		FreeBank zo\x 
		FreeBank zo\y 
		FreeBank zo\z 
	Next
	Delete Each zorder
End Function

Comments

fredborg
(Posted 22 years ago)
Here's another take on the same thing, based on Beakers code, but speeded up quite a bit. It also uses less memory :)

;
; Alpha Z-Ordering Mumbo Jumbo
;
; By Beaker and tweaked by Fredborg
;

;
; Zorder type
Type zorder
	Field mesh
	Field surf
	Field x,y,z			; Banks: size = tricnt * 6 bytes (3 shorts)
	Field n_tris		; Counttriangles(surf)-1
	Field include_y		; Include y axis sorting
	Field prev			; Last sorting axis
End Type

Function ZOrder_SortBank(bankA,bankB,l,r)
	Local p,q,h,x#
	p=l
	q=r
	x=PeekFloat(bankA,((l+r)/2)*4)
	Repeat
		While PeekFloat(bankA,p*4)>x
			p=p+1
		Wend
		While x>PeekFloat(bankA,q*4)
			q=q-1
		Wend
		If p>q Then Exit
		
		;SWAP------------------
		v0 = PeekShort(bankB,q*6 + 0)
		v1 = PeekShort(bankB,q*6 + 2)
		v2 = PeekShort(bankB,q*6 + 4)

		PokeShort bankB,q*6 + 0,PeekShort(bankB,p*6 + 0)
		PokeShort bankB,q*6 + 2,PeekShort(bankB,p*6 + 2)
		PokeShort bankB,q*6 + 4,PeekShort(bankB,p*6 + 4)
				
		PokeShort bankB,p*6 + 0,v0
		PokeShort bankB,p*6 + 2,v1
		PokeShort bankB,p*6 + 4,v2

		f# = PeekFloat(bankA,q*4)
		PokeFloat bankA,q*4,PeekFloat(bankA,p*4)
		PokeFloat bankA,p*4,f#	
		;----------------------
		
		p=p+1
		q=q-1
		If q<0 Then Exit
	Forever 
	If l<q Then ZOrder_SortBank(bankA,bankB,l,q)
	If p<r Then ZOrder_SortBank(bankA,bankB,p,r)

End Function

Function ZOrder_Init.zorder(mesh, include_y = False)

	zo.zorder = New zorder
	zo\mesh = mesh
	zo\surf = GetSurface(zo\mesh,1)

	If zo\surf = 0
		RuntimeError "Zorderize(): No surface found!"
	EndIf

	zo\include_y = include_y

	zo\n_tris = CountTriangles(zo\surf)-1

	tempbank = CreateBank((zo\n_tris+1)*4)

	; X axis sorting
	zo\x = CreateBank((zo\n_tris+1)*6)
	For t = 0 To zo\n_tris
		ft = t*6
		PokeShort zo\x,ft+0,TriangleVertex(zo\surf,t,0)
		PokeShort zo\x,ft+2,TriangleVertex(zo\surf,t,1)
		PokeShort zo\x,ft+4,TriangleVertex(zo\surf,t,2)
		PokeFloat tempbank,t*4,VertexX(zo\surf,TriangleVertex(zo\surf,t,0))+VertexX(zo\surf,TriangleVertex(zo\surf,t,1))+VertexX(zo\surf,TriangleVertex(zo\surf,t,2))
	Next
	ZOrder_SortBank(tempbank,zo\x,0,zo\n_tris)

	If include_y
		; Y axis sorting
		zo\y = CreateBank((zo\n_tris+1)*6)
		For t = 0 To zo\n_tris
			ft = t*6
			PokeShort zo\y,ft+0,TriangleVertex(zo\surf,t,0)
			PokeShort zo\y,ft+2,TriangleVertex(zo\surf,t,1)
			PokeShort zo\y,ft+4,TriangleVertex(zo\surf,t,2)
			PokeFloat tempbank,t*4,VertexY(zo\surf,TriangleVertex(zo\surf,t,0))+VertexY(zo\surf,TriangleVertex(zo\surf,t,1))+VertexY(zo\surf,TriangleVertex(zo\surf,t,2))
		Next
		ZOrder_SortBank(tempbank,zo\y,0,zo\n_tris)
	EndIf
	
	; Z axis sorting
	zo\z = CreateBank((zo\n_tris+1)*6)
	For t = 0 To zo\n_tris
		ft = t*6
		PokeShort zo\z,ft+0,TriangleVertex(zo\surf,t,0)
		PokeShort zo\z,ft+2,TriangleVertex(zo\surf,t,1)
		PokeShort zo\z,ft+4,TriangleVertex(zo\surf,t,2)
		PokeFloat tempbank,t*4,VertexZ(zo\surf,TriangleVertex(zo\surf,t,0))+VertexZ(zo\surf,TriangleVertex(zo\surf,t,1))+VertexZ(zo\surf,TriangleVertex(zo\surf,t,2))
	Next
	ZOrder_SortBank(tempbank,zo\z,0,zo\n_tris)
	
	FreeBank tempbank
	
	Return zo
	
End Function


Function ZOrder_Update(zo.zorder,cam)
	
	Local t,tf
	
	TFormVector 0,0,1, cam,0
	Local tx# = TFormedX()
	Local ty# = TFormedY()
	Local tz# = TFormedZ()
	
	Local temp = 0
	If zo\include_y = False Then ty = 0.0
	If (Abs(tx) > Abs(tz)) And (Abs(tx) > Abs(ty))
		temp = Sgn(tx)
		bank = zo\x
	ElseIf Abs(ty) > Abs(tz)
		temp = Sgn(ty)*2
		bank = zo\y
	Else
		temp = Sgn(tz)*3
		bank = zo\z
	EndIf
	
	If temp<>zo\prev
	
		zo\prev = temp
		ClearSurface zo\surf,0,1
					
		Select Sgn(zo\prev)
			Case 1:
				For t = 0 To zo\n_tris
					tf = t*6
					AddTriangle ( zo\surf,PeekShort(bank,tf),PeekShort(bank,tf+2),PeekShort(bank,tf+4) )
				Next
			Case -1:
				For t = zo\n_tris To 0 Step -1
					tf = t*6
					AddTriangle ( zo\surf,PeekShort(bank,tf),PeekShort(bank,tf+2),PeekShort(bank,tf+4) )
				Next
		End Select
		
	EndIf
	
End Function

Function ZOrder_Free(zo.zorder)

	If zo = Null
		For zo.zorder = Each zorder
			If zo\x Then FreeBank zo\x
			If zo\y Then FreeBank zo\y
			If zo\z Then FreeBank zo\z
			Delete zo
		Next
	Else
		If zo\x Then FreeBank zo\x
		If zo\y Then FreeBank zo\y
		If zo\z Then FreeBank zo\z
		Delete zo
	EndIf

End Function


Filax
(Posted 22 years ago)
Maybe can you post an example freborg ?

fredborg
(Posted 22 years ago)
Sure, here is a small one:
Graphics3D 640,480,0,2
SetBuffer BackBuffer()

Include "zorder.bb"

b = CreateBrush()
BrushFX b,1+2+16+32

m = CreateMesh()
s = CreateSurface(m,b)

size# = 5.0
hsize# = size/2.0

For i = 0 To 1000
	x# = Rnd(-50,50)
	z# = Rnd(-50,50)
	
	a# = Rand(0,3)*90
	xx# = Sin(a)*hsize
	zz# = Cos(a)*hsize
	
	v0 = AddVertex(s,x-xx,0,z-zz)
		VertexColor s,v0,Rand(128,255),Rand(128,255),Rand(128,255),Rnd(0,1)
	v1 = AddVertex(s,x-xx,size,z-zz)
		VertexColor s,v1,Rand(128,255),Rand(128,255),Rand(128,255),Rnd(0,1)
	v2 = AddVertex(s,x+xx,size,z+zz)
		VertexColor s,v2,Rand(128,255),Rand(128,255),Rand(128,255),Rnd(0,1)
	v3 = AddVertex(s,x+xx,0,z+zz)
		VertexColor s,v3,Rand(128,255),Rand(128,255),Rand(128,255),Rnd(0,1)
		
	AddTriangle s,v0,v1,v2
	AddTriangle s,v2,v3,v0
Next

;
; Prepare zordering for mesh m
zorder.zorder = ZOrder_Init(m)

doz = False;True

c = CreateCamera()
p# = 0
y# = 0

MoveMouse 320,240
Repeat
	
	p = p+MouseYSpeed()
	y = y-MouseXSpeed()
	RotateEntity c,p,y,0
	MoveEntity c,KeyDown(205)-KeyDown(203),0,KeyDown(200)-KeyDown(208)
	
	MoveMouse 320,240

	;
	; Toggle zordering on/off
	If KeyHit(57)
		doz = Not doz
	EndIf

	;
	; Update zordering for mesh m with camera c
	If doz
		ZOrder_Update(zorder,c)
	EndIf

	RenderWorld

	If doz
		Text 0,0,"Space to disable ZOrdering"
	Else
		Text 0,0,"Space to enable ZOrdering"
	EndIf
	Flip
	
Until KeyHit(1)

End


Dark Half
(Posted 21 years ago)
Bare in mind, that this system (Fredborg's) won't work if you modify the mesh after you have inited the system (tried it on my cloud system, after modifying the position of some of the 'sprites' it wont work).

Although, a very nice system fredborg !

Beaker
(Posted 21 years ago)
This is true. My system only works on static meshes (or mostly static, for example: animated grass, trees etc).

t3K|Mac
(Posted 21 years ago)
i get a surface index out of range when using this code on a loadanimmesh() mesh. any hints?

Beaker
(Posted 21 years ago)
Probably because your base entity isn't a mesh (probly a pivot). You can check it with something like:
If EntityClass(myEntity) <> "Mesh" Then Print "No mesh here"

t3K|Mac
(Posted 21 years ago)
i have several meshes and pivots mixed in this loadanimmesh()-mesh. do i have to delete all the pivots to get zorder to work? or do i have to make sure that the base entity is a mesh?

Beaker
(Posted 21 years ago)
Neither. It expects to recieve a single mesh. And can only sort one mesh to be visually correct (AFAIR). For example: a lot of grass, a lot of leaves, but not both.

There is a way to get it to work on both grass and leaves, but it involves combining the grass and leaf textures into one, and also combining the meshes.

t3K|Mac
(Posted 21 years ago)
ohmygod - i have 260 meshes (in one loadanimmesh)... ok i see i have a problem.... hmmmmm

Beaker
(Posted 21 years ago)
Actually, regarding the grass/leaves example I give above, you wouldn't need to combine them as long as they never visually overlap each other. But, you would need to pass them both seperately to the Zorder.

Beaker
(Posted 21 years ago)
[EDIT: discussion here:
http://www.blitzbasic.com/Community/posts.php?topic=59416 ]

Here is a new version that (a) works better with animated meshes (rotation) and (b) you can optionally
just supply a particular surface to zorderize, using this syntax:
ZOrder_Init(mesh, surf=0, y_include=False)

Here is the new library:
;
; Alpha Z-Ordering Mumbo Jumbo
;
; By Beaker and tweaked by Fredborg - retweaked by Beaker :)
;

;
; Zorder type
Type zorder
	Field mesh
	Field surf
	Field x,y,z			; Banks: size = tricnt * 6 bytes (3 shorts)
	Field n_tris		; Counttriangles(surf)-1
	Field include_y		; Include y axis sorting
	Field prev			; Last sorting axis
End Type

Function ZOrder_SortBank(bankA,bankB,l,r)
	Local p,q,h,x#
	p=l
	q=r
	x=PeekFloat(bankA,((l+r)/2)*4)
	Repeat
		While PeekFloat(bankA,p*4)>x
			p=p+1
		Wend
		While x>PeekFloat(bankA,q*4)
			q=q-1
		Wend
		If p>q Then Exit
		
		;SWAP------------------
		v0 = PeekShort(bankB,q*6 + 0)
		v1 = PeekShort(bankB,q*6 + 2)
		v2 = PeekShort(bankB,q*6 + 4)

		PokeShort bankB,q*6 + 0,PeekShort(bankB,p*6 + 0)
		PokeShort bankB,q*6 + 2,PeekShort(bankB,p*6 + 2)
		PokeShort bankB,q*6 + 4,PeekShort(bankB,p*6 + 4)
				
		PokeShort bankB,p*6 + 0,v0
		PokeShort bankB,p*6 + 2,v1
		PokeShort bankB,p*6 + 4,v2

		f# = PeekFloat(bankA,q*4)
		PokeFloat bankA,q*4,PeekFloat(bankA,p*4)
		PokeFloat bankA,p*4,f#	
		;----------------------
		
		p=p+1
		q=q-1
		If q<0 Then Exit
	Forever 
	If l<q Then ZOrder_SortBank(bankA,bankB,l,q)
	If p<r Then ZOrder_SortBank(bankA,bankB,p,r)

End Function

Function ZOrder_Init.zorder(mesh, surf=0, include_y = False)

	zo.zorder = New zorder
	zo\mesh = mesh
	If surf = 0
		zo\surf = GetSurface(zo\mesh,1)
	Else
		zo\surf = surf
	EndIf

	If zo\surf = 0
		RuntimeError "Zorderize(): No surface found!"
	EndIf

	zo\include_y = include_y

	zo\n_tris = CountTriangles(zo\surf)-1

	tempbank = CreateBank((zo\n_tris+1)*4)

	; X axis sorting
	zo\x = CreateBank((zo\n_tris+1)*6)
	For t = 0 To zo\n_tris
		ft = t*6
		PokeShort zo\x,ft+0,TriangleVertex(zo\surf,t,0)
		PokeShort zo\x,ft+2,TriangleVertex(zo\surf,t,1)
		PokeShort zo\x,ft+4,TriangleVertex(zo\surf,t,2)
		PokeFloat tempbank,t*4,VertexX(zo\surf,TriangleVertex(zo\surf,t,0))+VertexX(zo\surf,TriangleVertex(zo\surf,t,1))+VertexX(zo\surf,TriangleVertex(zo\surf,t,2))
	Next
	ZOrder_SortBank(tempbank,zo\x,0,zo\n_tris)

	If include_y
		; Y axis sorting
		zo\y = CreateBank((zo\n_tris+1)*6)
		For t = 0 To zo\n_tris
			ft = t*6
			PokeShort zo\y,ft+0,TriangleVertex(zo\surf,t,0)
			PokeShort zo\y,ft+2,TriangleVertex(zo\surf,t,1)
			PokeShort zo\y,ft+4,TriangleVertex(zo\surf,t,2)
			PokeFloat tempbank,t*4,VertexY(zo\surf,TriangleVertex(zo\surf,t,0))+VertexY(zo\surf,TriangleVertex(zo\surf,t,1))+VertexY(zo\surf,TriangleVertex(zo\surf,t,2))
		Next
		ZOrder_SortBank(tempbank,zo\y,0,zo\n_tris)
	EndIf
	
	; Z axis sorting
	zo\z = CreateBank((zo\n_tris+1)*6)
	For t = 0 To zo\n_tris
		ft = t*6
		PokeShort zo\z,ft+0,TriangleVertex(zo\surf,t,0)
		PokeShort zo\z,ft+2,TriangleVertex(zo\surf,t,1)
		PokeShort zo\z,ft+4,TriangleVertex(zo\surf,t,2)
		PokeFloat tempbank,t*4,VertexZ(zo\surf,TriangleVertex(zo\surf,t,0))+VertexZ(zo\surf,TriangleVertex(zo\surf,t,1))+VertexZ(zo\surf,TriangleVertex(zo\surf,t,2))
	Next
	ZOrder_SortBank(tempbank,zo\z,0,zo\n_tris)
	
	FreeBank tempbank
	
	Return zo
	
End Function


Function ZOrder_Update(zo.zorder,cam)
	
	Local t,tf
	
	TFormVector 0,0,1, cam,zo\mesh
	Local tx# = TFormedX()
	Local ty# = TFormedY()
	Local tz# = TFormedZ()
	
	Local temp = 0
	If zo\include_y = False Then ty = 0.0
	If (Abs(tx) > Abs(tz)) And (Abs(tx) > Abs(ty))
		temp = Sgn(tx)
		bank = zo\x
	ElseIf Abs(ty) > Abs(tz)
		temp = Sgn(ty)*2
		bank = zo\y
	Else
		temp = Sgn(tz)*3
		bank = zo\z
	EndIf
	
	If temp<>zo\prev
	
		zo\prev = temp
		ClearSurface zo\surf,0,1
					
		Select Sgn(zo\prev)
			Case 1:
				For t = 0 To zo\n_tris
					tf = t*6
					AddTriangle ( zo\surf,PeekShort(bank,tf),PeekShort(bank,tf+2),PeekShort(bank,tf+4) )
				Next
			Case -1:
				For t = zo\n_tris To 0 Step -1
					tf = t*6
					AddTriangle ( zo\surf,PeekShort(bank,tf),PeekShort(bank,tf+2),PeekShort(bank,tf+4) )
				Next
		End Select
		
	EndIf
	
End Function

Function ZOrder_Free(zo.zorder)

	If zo = Null
		For zo.zorder = Each zorder
			If zo\x Then FreeBank zo\x
			If zo\y Then FreeBank zo\y
			If zo\z Then FreeBank zo\z
			Delete zo
		Next
	Else
		If zo\x Then FreeBank zo\x
		If zo\y Then FreeBank zo\y
		If zo\z Then FreeBank zo\z
		Delete zo
	EndIf

End Function


And here is new example code:
Graphics3D 640,480,0,2
SetBuffer BackBuffer()

Include "zorder.bb"

b = CreateBrush()
BrushFX b,1+2+16+32

m = CreateMesh()
s = CreateSurface(m,b)

size# = 5.0
hsize# = size/2.0

For i = 0 To 1000
	x# = Rnd(-50,50)
	z# = Rnd(-50,50)
	
	a# = Rand(0,3)*90
	xx# = Sin(a)*hsize
	zz# = Cos(a)*hsize
	
	v0 = AddVertex(s,x-xx,0,z-zz)
		VertexColor s,v0,Rand(128,255),Rand(128,255),Rand(128,255),Rnd(0.5,1)
	v1 = AddVertex(s,x-xx,size,z-zz)
		VertexColor s,v1,Rand(128,255),Rand(128,255),Rand(128,255),Rnd(0.5,1)
	v2 = AddVertex(s,x+xx,size,z+zz)
		VertexColor s,v2,Rand(128,255),Rand(128,255),Rand(128,255),Rnd(0.5,1)
	v3 = AddVertex(s,x+xx,0,z+zz)
		VertexColor s,v3,Rand(128,255),Rand(128,255),Rand(128,255),Rnd(0.5,1)
		
	AddTriangle s,v0,v1,v2
	AddTriangle s,v2,v3,v0
Next

;
; Prepare zordering for mesh m
zorder.zorder = ZOrder_Init(m)

doz = False;True

c = CreateCamera()
p# = 0
y# = 0

MoveMouse 320,240
Repeat
	
	p = p+MouseYSpeed()
	y = y-MouseXSpeed()
	RotateEntity c,p,y,0
	MoveEntity c,KeyDown(205)-KeyDown(203),0,KeyDown(200)-KeyDown(208)
	PositionEntity c,EntityX(c),2,EntityZ(c)

	TurnEntity m,0,0.5,0
	
	MoveMouse 320,240

	;
	; Toggle zordering on/off
	If KeyHit(57)
		doz = Not doz
	EndIf

	;
	; Update zordering for mesh m with camera c
	If doz
		ZOrder_Update(zorder,c)
	EndIf

	RenderWorld

	If doz
		Text 0,0,"Space to disable ZOrdering"
	Else
		Text 0,0,"Space to enable ZOrdering"
	EndIf
	Flip
	
Until KeyHit(1)

End


jfk EO-11110
(Posted 21 years ago)
isn't the random z-order problem only affecting triangles of one mesh, so does it actualy make sense to add several meshes together?

And to t3k: there is a command in blitz that tells you if an entity is a mesh, a pivot or whatever:

http://www.blitzbasic.com/b3ddocs/command.php?name=entityclass&ref=goto

So you maybe have to parse the animmesh recursively and make a list of all children that are meshes.

Code Archives Forum