Splitting a mesh into separate tris

Blitz3D Forums/Blitz3D Programming/Splitting a mesh into separate tris

big10p(Posted 2003) [#1]
Hi

Can anyone tell me how I can have a mesh - say, a simple cube - and then blow it apart into it's separate tris using a particle effect?

thanks


podperson(Posted 2003) [#2]
Well, you need to create a new mesh, then walk through the mesh you started with and create a new surface in the new mesh for each triangle in the old mesh. (If you're feeling very clever you might like to extrude each triangle a bit along its normal and thus explode into "solid" pieces...)

Then you swap the new mesh for the old one and fly its surfaces away...


big10p(Posted 2003) [#3]
OK, I see. I think I'm getting a bit in front of myself as I'm pretty new to B3D and haven't quite grasped the concept of surfaces yet. A bit more study is in order, i think, but thanks for pointing me in the right direction. I like the idea of making solid pieces, too. ;)

Cheers


makakoman(Posted 2003) [#4]
I think there is an Unweld function in the code archives. This function will loop through your mesh and make sure that no tirangles are sharing the same vertex. That way you can move each triangle individually without affecting another triangle. The easiest thing to do is probably:

newMesh = CopyMesh(oldMesh)

Unweld(newMesh)

Loop through triangles in newMesh continuously altering the VertexCoords of them to follow the motion for the explosion until you are done.

FreeEntity(newMesh)

Note: I don't think you would want a new surface per triangle, it would slow your program to a crawl with all of those surfaces.

Regards,
MK


big10p(Posted 2003) [#5]
Thanks, I found the unweld function in the archives but it's late and I've had a few beers so I'll look at it tomorrow. :)

If I understand you, it's going to be more difficult than I hoped it'd be if I have to manipulate all three verts of a triangle to make it 'explode' away. Is there no way I can treat each tri like a separate entity and just use TurnEntity, TranslateEntity etc. to do the explosion?

Are there any demos about that 'explode a mesh'?

Thanks again


3D(Posted 2003) [#6]
try the explode demo in the samples folder in blitz
Blitz3D\samples\birdie\Explode
i think this will help you


makakoman(Posted 2003) [#7]
@big10p, just a quick suggestion, if you wanted to treat each triangle like an entity, you could create a single triangle mesh and make it invisible. Then for each triangle in your exploding mesh, set the vertex coords of your single triangle mesh to the same and then use rotate, turn, position, etc, and then copy the vertex coords back to the exploding triangle. I don't think this would be too slow, although I have not tried it. It's a cheat, but it could work.

Good luck,
MK


big10p(Posted 2003) [#8]
3D: Thanks, that seems to be just what I was looking for.

makakoman: That's really quite a neat idea. :) I've got some experimenting/investigating to do - thanks for all the help, folks.


Neo Genesis10(Posted 2003) [#9]
I managed this feat some time ago heres the code if you're interested...

Type tris
	Field ent
End Type

Function ExplodeMesh( mesh )

	For s = 1 To CountSurfaces( mesh )
		surf = GetSurface( mesh, s )
		For t = 1 to CountTriangles( surf )
			triangle = CreateMesh()
			trisurf = CreateSurface( triangle )

			v0 = TriangleVertex( surf, t, 0 )
			v1 = TriangleVertex( surf, t, 1 )
			v2 = TriangleVertex( surf, t, 2 )

			AddVertex trisurf, VertexX#(surf, v0), VertexY#(surf, v0), VertexZ#(surf, v0), VertexU#(surf, v0), VertexV#(surf, v0)
			AddVertex trisurf, VertexX#(surf, v1), VertexY#(surf, v1), VertexZ#(surf, v1), VertexU#(surf, v1), VertexV#(surf, v1)
			AddVertex trisurf, VertexX#(surf, v2), VertexY#(surf, v2), VertexZ#(surf, v2), VertexU#(surf, v2), VertexV#(surf, v2)
			AddTriangle trisurf, v0, v1, v2
			tri.tris = New tris	; Add this triangle to the tris list
			tris\ent = triangle
		Next
	Next
	FreeEntity mesh	; Disintegrate old mesh (remove if necessary)

End Function
Enjoy :)


DarkEagle(Posted 2003) [#10]
you do know how many surfaces that is going to create for even a low poly model?


Neo Genesis10(Posted 2003) [#11]
DarkEagle: Yup. But it DOES do the trick. I've had some recent attempts at shattering a mesh and dynamically positioning the triangles to give an explosion effect (all using a single surface and brush) but trying to keep track of each triangle is murder... :)


big10p(Posted 2003) [#12]
Hi, back again after much experimenting and head scratching. Think I've managed to crack the prob though. :) See code below.

I decided the best way to go was not to have a separate entity for each tri but instead to keep everything contained within a single mesh (and, optionally, a single surface). I went with makakoman's idea of using a single tri 'scratch pad' mesh to do the per-tri rotations but this proved a bit more complicated than I first thought - basically, I had to calculate a 'centre of tri' vertex for every tri in order to do it. It seems to run fairly quickly, too.

I also built in recursive tri subdivision (my brain 'erts) in order to give the explosions lots of pieces to blow apart. This is useful when exploding meshes with very large tris, like cubes which only normally have 2 tris per side.

Anyways, let me know what you think.

;
; Explodable mesh demo.
; 
; Chris Chadwick 2003
;

	Graphics3D 800,600,32

	WireFrame 0
	AntiAlias 0

	SeedRnd MilliSecs()

	; Create a check pattern texture.
	tex = CreateTexture(64,64)
	SetBuffer TextureBuffer(tex)
	For y = 0 To 63 Step 4
		For x = 0 To 63 Step 2
			If c Then Color 255,255,255 Else Color 255,0,0
			c = Not c
			Rect x,y,2,4
		Next
		c = Not c
	Next
	SetBuffer BackBuffer()
	Color 255,255,255

	; Set to value between 0 and 1 to say when during an explosion animation
	; the pieces should start to fade out.
	; e.g. 1 to start immediately, .5 to start halfway through, 0 to never fade.
	Const FADE_START# = 0.5
		
	Type tri_linkT
		Field prev.tri_linkT
		Field surf
		Field tri
		Field dx#,dy#,dz#
		Field pitch#,yaw#,roll#
	End Type

	Type explode_ctrlT
		Field tri_list.tri_linkT
		Field mesh
		Field life%
		Field fader#
		Field fade_start%
		Field exploding%
	End Type	
	
	Global frame_count%
	Global fps%
	Global fps_timeout%
	Global frame_time%
	Global slowest_frame%
	Global frame_start%
	fps_timer = CreateTimer(60)


	Global cam = CreateCamera()
	PositionEntity cam,0,0,-8
	
	light = CreateLight()
	TurnEntity light,0,90,0
	
	; Scratch pad single tri mesh for doing rotations.
	Global tri_mesh = CreateMesh()
	Global tri_surf = CreateSurface(tri_mesh)
	AddVertex(tri_surf,0,0,0)
	AddVertex(tri_surf,0,0,0)
	AddVertex(tri_surf,0,0,0)
	AddTriangle(tri_surf,0,1,2)
	HideEntity tri_mesh

	; Scratch pad mesh used by copy_tri_explode().
	Global t_mesh = CreateMesh()
	Global t_surf = CreateSurface(t_mesh)
	HideEntity t_mesh
	
	cube = CreateCube()
	sphere = CreateSphere(16)
	diamond = CreateSphere(2)
	pyramid = CreateCone(4)
	cone = CreateCone(16)
	cylinder = CreateCylinder(16)
		
	shape1.explode_ctrlT = copy_mesh_explode(cube,200,3)
	PositionEntity shape1\mesh,-4,-1.5,0
	EntityTexture shape1\mesh,tex
		
	shape2.explode_ctrlT = copy_mesh_explode(sphere,200)
	PositionEntity shape2\mesh,0,-1.5,0
	EntityTexture shape2\mesh,tex

	shape3.explode_ctrlT = copy_mesh_explode(cone,200,2)
	PositionEntity shape3\mesh,4,-1.5,0
	EntityTexture shape3\mesh,tex

	shape4.explode_ctrlT = copy_mesh_explode(cylinder,200,2)
	PositionEntity shape4\mesh,4,3,0
	EntityTexture shape4\mesh,tex

	shape5.explode_ctrlT = copy_mesh_explode(diamond,200,3)
	PositionEntity shape5\mesh,0,3,0
	EntityTexture shape5\mesh,tex

	shape6.explode_ctrlT = copy_mesh_explode(pyramid,200,3)
	PositionEntity shape6\mesh,-4,3,0
	EntityTexture shape6\mesh,tex

	FreeEntity cube
	FreeEntity sphere
	FreeEntity diamond
	FreeEntity cone
	FreeEntity cylinder
	FreeEntity pyramid
	
	; Main loop
	While Not KeyHit(1)

		frame_start = MilliSecs()

		If KeyHit(57) Then bang = True

		For ctrl.explode_ctrlT = Each explode_ctrlT
			If ctrl\exploding = False
				If bang
					bang = False
					ctrl\exploding = True
					EntityFX ctrl\mesh,16
				Else				
					TurnEntity ctrl\mesh,1,0,.5
				EndIf
			EndIf
		Next
		
		update_mesh_explode()
		
		UpdateWorld
		RenderWorld

		Text 400,550,"Press SPACE to explode a shape!",1

		frame_time = MilliSecs() - frame_start	
		show_info()
				
		WaitTimer(fps_timer)
		Flip(1)

	Wend
	
	ClearWorld
	End




;
; Updates ALL explodable meshes that are currently exploding.
;
Function update_mesh_explode()

	For this.explode_ctrlT = Each explode_ctrlT
		
		If this\exploding
			
			If this\life
				tri.tri_linkT = this\tri_list
			
				If this\life <= this\fade_start
					EntityAlpha this\mesh,this\life * this\fader
				EndIf
				
				; Update all tris in linked list.
				While tri <> Null
					v0 = TriangleVertex(tri\surf,tri\tri,0)
					v1 = TriangleVertex(tri\surf,tri\tri,1)
					v2 = TriangleVertex(tri\surf,tri\tri,2)

					x0# = VertexX(tri\surf,v0)
					y0# = VertexY(tri\surf,v0)
					z0# = VertexZ(tri\surf,v0)
					x1# = VertexX(tri\surf,v1)
					y1# = VertexY(tri\surf,v1)
					z1# = VertexZ(tri\surf,v1)
					x2# = VertexX(tri\surf,v2)
					y2# = VertexY(tri\surf,v2)
					z2# = VertexZ(tri\surf,v2)
					cx# = VertexX(tri\surf,v2+1)
					cy# = VertexY(tri\surf,v2+1)
					cz# = VertexZ(tri\surf,v2+1)
			
					; Load scratch pad tri mesh.
					VertexCoords tri_surf,0,x0-cx,y0-cy,z0-cz
					VertexCoords tri_surf,1,x1-cx,y1-cy,z1-cz
					VertexCoords tri_surf,2,x2-cx,y2-cy,z2-cz
					VertexNormal tri_surf,0,VertexNX(tri\surf,v0),VertexNY(tri\surf,v0),VertexNZ(tri\surf,v0)
					VertexNormal tri_surf,1,VertexNX(tri\surf,v1),VertexNY(tri\surf,v1),VertexNZ(tri\surf,v1)
					VertexNormal tri_surf,2,VertexNX(tri\surf,v2),VertexNY(tri\surf,v2),VertexNZ(tri\surf,v2)
			
					; Do rotations.
					RotateMesh tri_mesh,tri\pitch,tri\yaw,tri\roll
					
					; Copy back to mesh tri.
					x0# = VertexX(tri_surf,0)
					y0# = VertexY(tri_surf,0)
					z0# = VertexZ(tri_surf,0)
					x1# = VertexX(tri_surf,1)
					y1# = VertexY(tri_surf,1)
					z1# = VertexZ(tri_surf,1)
					x2# = VertexX(tri_surf,2)
					y2# = VertexY(tri_surf,2)
					z2# = VertexZ(tri_surf,2)
					
					VertexCoords tri\surf,v0,x0+cx+tri\dx,y0+cy+tri\dy,z0+cz+tri\dz
					VertexCoords tri\surf,v1,x1+cx+tri\dx,y1+cy+tri\dy,z1+cz+tri\dz
					VertexCoords tri\surf,v2,x2+cx+tri\dx,y2+cy+tri\dy,z2+cz+tri\dz
					VertexNormal tri\surf,v0,VertexNX(tri_surf,0),VertexNY(tri_surf,0),VertexNZ(tri_surf,0)
					VertexNormal tri\surf,v1,VertexNX(tri_surf,1),VertexNY(tri_surf,1),VertexNZ(tri_surf,1)
					VertexNormal tri\surf,v2,VertexNX(tri_surf,2),VertexNY(tri_surf,2),VertexNZ(tri_surf,2)
			
					VertexCoords tri\surf,v2+1,cx+tri\dx,cy+tri\dy,cz+tri\dz
					
					tri = tri\prev
				Wend
			
				this\life = this\life - 1
			Else
				; Mesh has finished exploding.
				free_mesh_explode(this)
			EndIf

		EndIf

	Next

End Function


;
; Creates a subdivided (optional), unwelded copy of an existing mesh.
; Explode info for all tris in the new mesh are kept in a separate linked list
; contained in the control variable returned to the caller.
; Note: the source mesh being copied remains completely unaltered.
;
; Params:
; s_mesh     - Source mesh to be copied.
; life       - Duration of explosion animation (in frames) to use when exploded.
; divs       - Number of times to perform x4 sub-division on each source tri.
; keep_surfs - True to keep the same amount of surfaces in
;              the copy as in the source mesh.
;              False (Default) to copy all tris in the source mesh
;              to a single surface in the copy.
;
; Returns:
; Pointer to the control variable (of type explode_ctrlT) for the
; new explodable mesh created.
;
Function copy_mesh_explode.explode_ctrlT(s_mesh,life%,divs=0,keep_surfs%=False)

	tri_list.tri_linkT = Null

	d_mesh = CreateMesh()
			
	For sno = 1 To CountSurfaces(s_mesh)
		
		s_surf = GetSurface(s_mesh,sno)
		nt = CountTriangles(s_surf)

		If sno = 1 Or keep_surfs Then d_surf = CreateSurface(d_mesh)
		
		For tno = 0 To nt-1
			tri_list = copy_tri_explode(s_surf,tno,d_surf,divs,tri_list)
		Next
	
	Next

	; Create and return this explodable mesh's control variable.
	ctrl.explode_ctrlT = New explode_ctrlT
	ctrl\tri_list = tri_list
	ctrl\mesh = d_mesh
	ctrl\life = life
	ctrl\fade_start = Ceil(Float(life)*FADE_START#)
	ctrl\fader = 1.0/(ctrl\fade_start+1)
	ctrl\exploding = False
		
	Return ctrl
	
End Function


;
; Adds an unwelded copy of a tri from the source surface to the destination
; surface, performing any sub-division requested.
;
; Sub-division is done by calling this function recursively, splitting the
; source tri into 4 unwelded tris each time, like so:
;
;           v1
;           /\ 
;         /____\
;       /  \  /  \
;     /_____\/_____\
;    v0            v2
;
; Params:
; s_surf   - Source surface containing tri to be copied.
; tri      - Index of tri to be copied.
; d_surf   - Destination surface to copy the source tri to.
; divs     - Number of times to perform x4 sub-division on the source tri.
; tri_list - Current top item in the linked list.
; reset    - True (default) to clear scratch pad mesh.
;            False to not clear scratch pad mesh (used internally only!).
;
; Returns:
; The current top item in the linked list.
;
Function copy_tri_explode.tri_linkT(s_surf,tri,d_surf,divs,tri_list.tri_linkT,reset%=True)

	If reset Then ClearSurface(t_surf)
	
	sv0 = TriangleVertex(s_surf,tri,0)
	sv1 = TriangleVertex(s_surf,tri,1)
	sv2 = TriangleVertex(s_surf,tri,2)

	; Get coords of all 3 vertices of source tri.
	x0# = VertexX(s_surf,sv0)
	y0# = VertexY(s_surf,sv0)
	z0# = VertexZ(s_surf,sv0)
	x1# = VertexX(s_surf,sv1)
	y1# = VertexY(s_surf,sv1)
	z1# = VertexZ(s_surf,sv1)
	x2# = VertexX(s_surf,sv2)
	y2# = VertexY(s_surf,sv2)
	z2# = VertexZ(s_surf,sv2)
	
	; Get normals of all 3 vertices of source tri.
	nx0# = VertexNX(s_surf,sv0)
	ny0# = VertexNY(s_surf,sv0)
	nz0# = VertexNZ(s_surf,sv0)
	nx1# = VertexNX(s_surf,sv1)
	ny1# = VertexNY(s_surf,sv1)
	nz1# = VertexNZ(s_surf,sv1)
	nx2# = VertexNX(s_surf,sv2)
	ny2# = VertexNY(s_surf,sv2)
	nz2# = VertexNZ(s_surf,sv2)

	; Get tex coords of all 3 vertices of source tri.
	u0# = VertexU(s_surf,sv0)
	v0# = VertexV(s_surf,sv0)
	w0# = VertexW(s_surf,sv0)
	u1# = VertexU(s_surf,sv1)
	v1# = VertexV(s_surf,sv1)
	w1# = VertexW(s_surf,sv1)
	u2# = VertexU(s_surf,sv2)
	v2# = VertexV(s_surf,sv2)
	w2# = VertexW(s_surf,sv2)

	; Get colour of all 3 vertices of source tri.
	r0# = VertexRed(s_surf,sv0)
	g0# = VertexGreen(s_surf,sv0)
	b0# = VertexBlue(s_surf,sv0)
	r1# = VertexRed(s_surf,sv1)
	g1# = VertexGreen(s_surf,sv1)
	b1# = VertexBlue(s_surf,sv1)
	r2# = VertexRed(s_surf,sv2)
	g2# = VertexGreen(s_surf,sv2)
	b2# = VertexBlue(s_surf,sv2)

	If divs
		; Calculate coords of the 3 discrete vertices used by sub-division.
		x3# = x0 + ((x1-x0)/2)
		y3# = y0 + ((y1-y0)/2)
		z3# = z0 + ((z1-z0)/2)
		x4# = x1 + ((x2-x1)/2)
		y4# = y1 + ((y2-y1)/2)
		z4# = z1 + ((z2-z1)/2)
		x5# = x2 + ((x0-x2)/2)
		y5# = y2 + ((y0-y2)/2)
		z5# = z2 + ((z0-z2)/2)
		
		; Calculate normals of the 3 discrete vertices used by sub-division.
		nx3# = nx0 + ((nx1-nx0)/2)
		ny3# = ny0 + ((ny1-ny0)/2)
		nz3# = nz0 + ((nz1-nz0)/2)
		nx4# = nx1 + ((nx2-nx1)/2)
		ny4# = ny1 + ((ny2-ny1)/2)
		nz4# = nz1 + ((nz2-nz1)/2)
		nx5# = nx2 + ((nx0-nx2)/2)
		ny5# = ny2 + ((ny0-ny2)/2)
		nz5# = nz2 + ((nz0-nz2)/2)
	
		; Calculate tex coords of the 3 discrete vertices used by sub-division.
		u3# = u0 + ((u1-u0)/2)
		v3# = v0 + ((v1-v0)/2)
		w3# = w0 + ((w1-w0)/2)
		u4# = u1 + ((u2-u1)/2)
		v4# = v1 + ((v2-v1)/2)
		w4# = w1 + ((w2-w1)/2)
		u5# = u2 + ((u0-u2)/2)
		v5# = v2 + ((v0-v2)/2)
		w5# = w2 + ((w0-w2)/2)
	
		; Calculate colour of the 3 discrete vertices used by sub-division.
		r3# = r0 + ((r1-r0)/2)
		g3# = g0 + ((g1-g0)/2)
		b3# = b0 + ((b1-b0)/2)
		r4# = r1 + ((r2-r1)/2)
		g4# = g1 + ((g2-g1)/2)
		b4# = b1 + ((b2-b1)/2)
		r5# = r2 + ((r0-r2)/2)
		g5# = g2 + ((g0-g2)/2)
		b5# = b2 + ((b0-b2)/2)
		
		; Add the 4 unwelded tris comprising the sub-division to the
		; temporary, scratch pad mesh surface.
		tv0 = AddVertex(t_surf,x0,y0,z0)
		tv3 = AddVertex(t_surf,x3,y3,z3)
		tv5 = AddVertex(t_surf,x5,y5,z5)
		tri0 = AddTriangle(t_surf,tv0,tv3,tv5)
		VertexNormal t_surf,tv0,nx0,ny0,nz0
		VertexNormal t_surf,tv3,nx3,ny3,nz3
		VertexNormal t_surf,tv5,nx5,ny5,nz5
		VertexColor t_surf,tv0,r0,g0,b0
		VertexColor t_surf,tv3,r3,g3,b3
		VertexColor t_surf,tv5,r5,g5,b5
		VertexTexCoords t_surf,tv0,u0,v0,w0
		VertexTexCoords t_surf,tv3,u3,v3,w3
		VertexTexCoords t_surf,tv5,u5,v5,w5
		
		tv1 = AddVertex(t_surf,x1,y1,z1)
		tv4 = AddVertex(t_surf,x4,y4,z4)
		tv3b = AddVertex(t_surf,x3,y3,z3)
		tri1 = AddTriangle(t_surf,tv1,tv4,tv3b)
		VertexNormal t_surf,tv1,nx1,ny1,nz1
		VertexNormal t_surf,tv4,nx4,ny4,nz4
		VertexNormal t_surf,tv3b,nx3,ny3,nz3
		VertexColor t_surf,tv1,r1,g1,b1
		VertexColor t_surf,tv4,r4,g4,b4
		VertexColor t_surf,tv3b,r3,g3,b3
		VertexTexCoords t_surf,tv1,u1,v1,w1
		VertexTexCoords t_surf,tv4,u4,v4,w4
		VertexTexCoords t_surf,tv3b,u3,v3,w3

		tv2 = AddVertex(t_surf,x2,y2,z2)
		tv5b = AddVertex(t_surf,x5,y5,z5)
		tv4b = AddVertex(t_surf,x4,y4,z4)
		tri2 = AddTriangle(t_surf,tv2,tv5b,tv4b)
		VertexNormal t_surf,tv2,nx2,ny2,nz2
		VertexNormal t_surf,tv5b,nx5,ny5,nz5
		VertexNormal t_surf,tv4b,nx4,ny4,nz4
		VertexColor t_surf,tv2,r2,g2,b2
		VertexColor t_surf,tv5b,r5,g5,b5
		VertexColor t_surf,tv4b,r4,g4,b4
		VertexTexCoords t_surf,tv2,u2,v2,w2
		VertexTexCoords t_surf,tv5b,u5,v5,w5
		VertexTexCoords t_surf,tv4b,u4,v4,w4
	
		tv3c = AddVertex(t_surf,x3,y3,z3)
		tv4c = AddVertex(t_surf,x4,y4,z4)
		tv5c = AddVertex(t_surf,x5,y5,z5)
		tri3 = AddTriangle(t_surf,tv3c,tv4c,tv5c)
		VertexNormal t_surf,tv3c,nx3,ny3,nz3
		VertexNormal t_surf,tv4c,nx4,ny4,nz4
		VertexNormal t_surf,tv5c,nx5,ny5,nz5
		VertexColor t_surf,tv3c,r3,g3,b3
		VertexColor t_surf,tv4c,r4,g4,b4
		VertexColor t_surf,tv5c,r5,g5,b5
		VertexTexCoords t_surf,tv3c,u3,v3,w3
		VertexTexCoords t_surf,tv4c,u4,v4,w4
		VertexTexCoords t_surf,tv5c,u5,v5,w5
	
		divs = divs - 1
	
		tri_list = copy_tri_explode(t_surf,tri0,d_surf,divs,tri_list,False)
		tri_list = copy_tri_explode(t_surf,tri1,d_surf,divs,tri_list,False)
		tri_list = copy_tri_explode(t_surf,tri2,d_surf,divs,tri_list,False)
		tri_list = copy_tri_explode(t_surf,tri3,d_surf,divs,tri_list,False)

	Else

		dv0 = AddVertex(d_surf,x0,y0,z0)
		dv1 = AddVertex(d_surf,x1,y1,z1)
		dv2 = AddVertex(d_surf,x2,y2,z2)
		
		; Calculate and add a lone 'centre of tri'
		; vertex (needed for per-tri rotations).
		tx# = x1 + ((x2-x1)/2)
		ty# = y1 + ((y2-y1)/2)
		tz# = z1 + ((z2-z1)/2)
		cvx# = tx - ((tx-x0)/3)
		cvy# = ty - ((ty-y0)/3)
		cvz# = tz - ((tz-z0)/3)
		AddVertex(d_surf,cvx,cvy,cvz)
		
		real_tri = AddTriangle(d_surf,dv0,dv1,dv2)
		
		VertexNormal d_surf,dv0,nx0,ny0,nz0
		VertexNormal d_surf,dv1,nx1,ny1,nz1
		VertexNormal d_surf,dv2,nx2,ny2,nz2
		VertexColor d_surf,dv0,r0,g0,b0
		VertexColor d_surf,dv1,r1,g1,b1
		VertexColor d_surf,dv2,r2,g2,b2
		VertexTexCoords d_surf,dv0,u0,v0,w0
		VertexTexCoords d_surf,dv1,u1,v1,w1
		VertexTexCoords d_surf,dv2,u2,v2,w2

		; Add this tri to the linked list.
		link.tri_linkT = New tri_linkT
		link\prev = tri_list
		link\surf = d_surf
		link\tri = real_tri
		r = Rnd(10,80)
		link\dx = cvx/r
		link\dy = cvy/r
		link\dz = cvz/r
		link\pitch = Rnd(-10,10)
		link\yaw = Rnd(-10,10)
		link\roll = Rnd(-10,10)

		tri_list = link	
	EndIf
	
	Return tri_list
	
End Function


;
; Free all mem used by an explodable mesh created with copy_mesh_explode().
;
; Params:
; ctrl - Control variable of the explodable mesh to be freed.
;
Function free_mesh_explode(ctrl.explode_ctrlT)

	this.tri_linkT = ctrl\tri_list
	
	While this <> Null
		delme.tri_linkT = this
		this = delme\prev
		Delete delme
	Wend
	
	FreeEntity ctrl\mesh
	Delete ctrl
	
End Function


;
; Display debug info.
;
Function show_info()
	
	frame_count = frame_count + 1

	If MilliSecs() > fps_timeout Then
		fps_timeout = MilliSecs() + 1000 
		fps = frame_count 
		frame_count = 0 
	EndIf 
	
	If frame_time > slowest_frame Then slowest_frame = frame_time
	
	Text 10,10," Triangles: " + TrisRendered()
	Text 10,25," Millisecs: " + frame_time
	Text 10,40,"   Slowest: " + slowest_frame
	Text 10,55,"       FPS: " + fps

End Function



makakoman(Posted 2003) [#13]
@big10p - Absolutely Awesome! This effect is really great. You should post it to the 3D Code archives.

Well done.

Thanks,
MK


WendellM(Posted 2003) [#14]
Wow, very nice! I agree that the archive would benefit from this.


big10p(Posted 2003) [#15]
OK, I'll put it up in the 3D archive. Thanks for the positive feedback!

Cheers.


big10p(Posted 2003) [#16]
Oops. Slight problem as I'm not calculating the vertex normals correctly when doing subdivision. This is most noticeable when looking at the lighting on the bottom of the cone and pyramid.

Unfortunately, maths isn't my strong point. Basically, given 2 vertex normals, I need to know how to calculate the normal of a vertex that lies between the two.

Any help with this would be much appreciated!

I think the way I'm doing it at the moment is basically correct except the normals are getting 'cropped' so that they don't have a length of 1.


Ross C(Posted 2003) [#17]
thats veeeeeeeery cool, and you say your new to 3d. impressive!


Neo Genesis10(Posted 2003) [#18]
Hey you managed what my brain hurt too much to attempt! Runs very smoothly - very nice indeed. Major kudos to the guy with the big 10p :)


big10p(Posted 2003) [#19]
Sorry to drag this post back up but for anyone interested, I've posted an updated version of my demo in the code archives. More bits and bobs added.

Click here!

Cheers

big10p


DJWoodgate(Posted 2003) [#20]
Blimey you don't do anything by halves do you! Most impressive.


big10p(Posted 2003) [#21]
lol, you're right - I struggle to develop anything without it suffering from outrageous 'feature creep'. Very annoying when I just want to knock-up something quickly but find myself still tinkering with it weeks, months or even years later! Bit of a personality flaw, I guess, I'm TRYING to keep under control. Being a perfectionist is OK up to a point, trouble is you rarely get anything finished! :)

Cheers

big10p