3d lines

Blitz3D Forums/Blitz3D Programming/3d lines

koekjesbaby(Posted 2003) [#1]
hi,

a while ago somebody posted something about lines in 3d. i also wanted to do those but i never found a satisfying answer untill this idea suddenly sprang into my mind (while walking home from the supermarket). it's a bit messy, since it's the frist thing that sprang into my mind, but i hope it can be of use for somebody out there (except me, because i am a very happy man at the moment).

here goes:
Function createline(x1#,y1#,z1#, x2#,y2#,z2#, mesh=0)
	
	If mesh = 0 Then 
		mesh=CreateMesh()
		EntityFX(mesh,16)
		surf=CreateSurface(mesh)	
		verts = 0	
	
		AddVertex surf,x1#,y1#,z1#,0,0
	Else
		surf = GetSurface(mesh,1)
		verts = CountVertices(surf)-1
	End If
	
	AddVertex surf,x2#,y2#,z2#,1,0

	AddTriangle surf,verts,verts+1,verts
	
	Return mesh
End Function

; --- set graphics
Graphics3D 640,480,32,0
SetBuffer(BackBuffer())

; --- create scene setup
camPiv = CreatePivot()
camera = CreateCamera(camPiv)
PositionEntity(camera, 0,0,-10)

light=CreateLight(2) 
PositionEntity(light,4,10,0) 
LightRange(light,10)

; --- create test cube
cube=CreateCube()
ScaleMesh(cube, 2,1,1)

; --- create lines
lines = createLine(2,1,1,    1,2,1)
lines = createLine(1,2,1,    0,2.3,1, lines)
lines = createLine(0,2.3,1, -1,2,1, lines)
lines = createLine(-1,2,1,  -2,1,1, lines)
EntityColor(lines, 255,0,0)

; okay, this is a bit cheating and very wrong/memory leak prone and shouldn't be used this way
; but i wanted To make more than one Line
; and not bother with typing even more hide- and showentity or rewriting the createline function:)
;
; yes, i am lazy ;)

lines = createLine(2,1,-1,    1,2,-1)
lines = createLine(1,2,-1,    0,2.3,-1, lines)
lines = createLine(0,2.3,-1, -1,2,-1, lines)
lines = createLine(-1,2,-1,  -2,1,-1, lines)
EntityColor(lines, 255,0,0)

lines = createLine(-3,1,1,   3,1,1)
EntityColor(lines, 255,0,0)
lines = createLine(-5,1,-1,  4,1,-1)
EntityColor(lines, 255,0,0)
lines = createLine(-4,-1,1,  3,-1,1)
EntityColor(lines, 255,0,0)
lines = createLine(-3,-1,-1, 5,-1,-1)
EntityColor(lines, 255,0,0)

TurnEntity(campiv, 35,35,35)

While Not KeyHit(1)

	; --- camera controls
	scrollwheel = MouseZSpeed()
	If MouseDown(1) Then 
		TurnEntity(camPiv, MouseYSpeed(),-MouseXSpeed(),0)
	Else If scrollwheel <> 0 Then 
		MoveEntity(camera, 0,0,scrollwheel*3)
	Else
		dummy = MouseYSpeed():dummy = MouseXSpeed():dummy = MouseZSpeed() ; prevent mousepeed blips.
	End If

	; --- rendering
	CameraClsMode(camera, 1, 1)
	WireFrame(0)
	HideEntity(lines)
	ShowEntity(cube)
	RenderWorld()
	
	CameraClsMode(camera, 0, 0)
	WireFrame(1)
	ShowEntity(lines)
	HideEntity(cube)
	RenderWorld()
	Flip()
Wend

End



Pepsi(Posted 2003) [#2]
Hiya koekjesbaby, I'm impressed.

I hadn't looked at it carefully enough to see why you think it's memory leak prone. Why is that?

I done something like this a long time ago BUT I either had to have all the 3d lines in front of solid polygons or behind them. On the second render pass with CameraClsMode(camera, 0, 0), is the zbuffer being disabled( no writes allowed, only z comparison ) in which it looks like the 3d lines are being drawn correctly behind the sold polys? If so, Alpha Polys should be able to work the same way this way( Which would IMHO be proper way of rendering alpha polys ).

I like this example thanks, it is code archivable! :)


Pepsi(Posted 2003) [#3]
This absolutely the best homemade 3D lines I've seen in Blitz3D yet! You deserve to be a very happy man for thinking this one up. This is very cool.


Beaker(Posted 2003) [#4]
It's old and crap but my graphics card doesnt show the lines. Just so you know. (Matrox G400)


koekjesbaby(Posted 2003) [#5]
yeah well, it kinda relies on wireframe to work properly, sorry. but thanks for the info.


Beaker(Posted 2003) [#6]
Thats not the problem. Wireframe does work correctly. Its because any triangle with 2 verts in the same position don't get drawn at all. It might be some form of optimisation. Having said that, I think it did make system unstable after running it a few times, so who knows.


ZJP(Posted 2003) [#7]
Hi,

Very, very good job.

@+


koekjesbaby(Posted 2003) [#8]
@masterbeaker:
very strange about the system unstability.
does this code works as it should on your matroxg400 card? (i sure hope so, lines should be available for everyone :)
Function createline(x1#,y1#,z1#, x2#,y2#,z2#, mesh=0)
	
	If mesh = 0 Then 
		mesh=CreateMesh()
		EntityFX(mesh,16)
		surf=CreateSurface(mesh)	
		verts = 0	
	
		AddVertex surf,x1#,y1#,z1#,0,0
	Else
		surf = GetSurface(mesh,1)
		verts = CountVertices(surf)-1
	End If
	
	AddVertex surf,x1#,y1#,z1#,0,0 ; or maybe change this to something like: AddVertex surf,x1#+0.001,y1#+0.001,z1#+0.001,0,0 
	AddVertex surf,x2#,y2#,z2#,1,0
	
	AddTriangle surf,verts,verts+2,verts+1
	


	Return mesh
End Function

; --- set graphics
Graphics3D 640,480,32,0
SetBuffer(BackBuffer())

; --- create scene setup
camPiv = CreatePivot()
camera = CreateCamera(camPiv)
PositionEntity(camera, 0,0,-10)

light=CreateLight(2) 
PositionEntity(light,4,10,0) 
LightRange(light,10)

; --- create test cube
cube=CreateCube()
ScaleMesh(cube, 2,1,1)
EntityAlpha(cube, 0.5)
cube2=CreateCube()
ScaleMesh(cube2, 1.8,0.8,0.8)

; --- create lines
lines = createLine(2,1,1,    1,2,1)
lines = createLine(1,2,1,    0,2.3,1, lines)
lines = createLine(0,2.3,1, -1,2,1, lines)
lines = createLine(-1,2,1,  -2,1,1, lines)
EntityColor(lines, 255,0,0)

; okay, this is a bit cheating and very wrong/memory leak prone and shouldn't be used this way (because freeEntity(lines) will only free the last line)
; but i wanted To make more than one Line
; and not bother with typing even more hide- and showentity or rewriting the createline function:)
;
; yes, i am lazy ;)

lines = createLine(2,1,-1,    1,2,-1)
lines = createLine(1,2,-1,    0,2.3,-1, lines)
lines = createLine(0,2.3,-1, -1,2,-1, lines)
lines = createLine(-1,2,-1,  -2,1,-1, lines)
EntityColor(lines, 255,0,0)

lines = createLine(-3,1,1,   3,1,1)
EntityColor(lines, 255,0,0)
lines = createLine(-5,1,-1,  4,1,-1)
EntityColor(lines, 255,0,0)
lines = createLine(-4,-1,1,  3,-1,1)
EntityColor(lines, 255,0,0)
lines = createLine(-3,-1,-1, 5,-1,-1)
EntityColor(lines, 255,0,0)

TurnEntity(campiv, 35,35,35)

While Not KeyHit(1)

	; --- camera controls
	scrollwheel = MouseZSpeed()
	If MouseDown(1) Then 
		TurnEntity(camPiv, MouseYSpeed(),-MouseXSpeed(),0)
	Else If scrollwheel <> 0 Then 
		MoveEntity(camera, 0,0,scrollwheel*3)
	Else
		dummy = MouseYSpeed():dummy = MouseXSpeed():dummy = MouseZSpeed() ; prevent mousepeed blips.
	End If

	; --- rendering
	CameraClsMode(camera, 1, 1)
	WireFrame(0)
	HideEntity(lines)
	ShowEntity(cube)
	ShowEntity(cube2)	
	RenderWorld()
	
	CameraClsMode(camera, 0, 0)
	WireFrame(1)
	ShowEntity(lines)
	HideEntity(cube)
	HideEntity(cube2)	
	RenderWorld()
	Flip()
Wend

End


heh, and i wanted to post some whitty remark about the GF4 noted in your sig, but you've already changed it :)


Beaker(Posted 2003) [#9]
It does display some red lines now (with that alternate Addvertex line in place). But, the lines don't hug the model, they go all over the place. Is that correct?


koekjesbaby(Posted 2003) [#10]
it should look like something this:

and the lines should remain pretty much where they are :)


koekjesbaby(Posted 2003) [#11]
or maybe change this line:
AddVertex surf,x1#,y1#,z1#,0,0; (or AddVertex surf,x1#+0.001,y1#+0.001,z1#+0.001,0,0)
to:
AddVertex surf,(x1#+x2#)/2,(y1#+y2#)/2,(z1#+z2#)/2,0,0
seems cleaner.


Beaker(Posted 2003) [#12]
Yes, thats what I see.


koekjesbaby(Posted 2003) [#13]
that's good to hear!

but my artistic effort is seen as "lines all over the place" ;)


Beaker(Posted 2003) [#14]
I was being polite. :D


koekjesbaby(Posted 2003) [#15]
yeah, yeah, yeah, aren't we all.


:)


leeluna(Posted 2003) [#16]
This is cool, I was aftr something like this ages ago to help me output plumbing pipe system models.

Good job!!!, by the way if it works on my dinosaur of a pc it should work on anything. PII 333,128MB,32MB Creative 3D card and win 98.


koekjesbaby(Posted 2003) [#17]
oops, to make the lines appear correctly behind the traparend cube the render part should be like:
CameraClsMode(camera, 1, 1)
	WireFrame(1)
	HideEntity(cube)
	HideEntity(cube2)	
	RenderWorld()
	
	CameraClsMode(camera, 0, 0)
	WireFrame(0)
	ShowEntity(cube)
	ShowEntity(cube2)	
	RenderWorld()


thanks for the feedback all, i really appreciate it.


Pepsi(Posted 2003) [#18]
Sweet! Thanks for sharing this very awsome piece of code with us and code archiving it, koekjesbaby. I know I would have never figured this one out with the CameraClsMode command. I've always hated the fact that Blitz3D never had proper 3d line primitive support. So what if this is a hack, it's clean and the best that I have ever seen for Blitz3D! I love little things likes this that can make a big difference in a project. In this case, now I don't have to worry about ever having to use ugly 2d lines to make a 3d-like grid in blitz3d anymore. Ace job you did there! :))))


koekjesbaby(Posted 2003) [#19]
thanks :)


MadsNy(Posted 2004) [#20]
Hi... hope any one will still read this topic :)..

My very good and kind friend fredborg coded this pice of line code for me...
<code>
Function Line3D(mesh,x0#,y0#,z0#,x1#,y1#,z1#)

If mesh = 0
mesh = CreateMesh()
surf = CreateSurface(mesh)
EntityFX mesh,1+16
Else
surf = GetSurface(mesh,1)
End If

v0 = AddVertex(surf,x0,y0,z0)
v1 = AddVertex(surf,x1,y1,z1)

; man kan også bare sige v2 = AddVertex(surf,x1,y1,z1)
v2 = AddVertex(surf,(x0+x1)*0.5,(y0+y1)*0.5,(z0+z1)*0.5)
AddTriangle surf,v0,v1,v2

Return mesh

End Function
</code>

and it works super fin,,,, but... there is problems, i have no clue where the problems might be, but when i draw more that 5000 "lines", faces i one mesh, my computer go into microsoft's_coolBlue screen mode.. just like guru meditation on amiga :)... yep i crash's totally...

what can the problem be, can you only throught mes modulation create around 5000 faces on one surface or in one mesh. ?????..

The thing is i need to draw at least 50000 lines, since im making a line trail on some boids, one trail pr. boid which will eventually become quite a few........

what can i do not to crash the program due to memory error every time. ?????


fredborg(Posted 2004) [#21]
Hi Mads :)

There is a limit to how many triangles and vertices a single surface can contain. So you need to add a new surface when you hit this limit. Nobody has managed to find out the exact limit, but it seems to be safe to use 30000 :) This function should automatically make you a new surface when you hit the limit.
Function Line3D(mesh,x0#,y0#,z0#,x1#,y1#,z1#) 

	If mesh = 0 
		mesh = CreateMesh() 
		surf = CreateSurface(mesh) 
		EntityFX mesh,1+16 
	Else 
		lastsurf = CountSurfaces(mesh)
		surf = GetSurface(mesh,lastsurf)
		If CountVertices(surf)>30000
			surf = CreateSurface(mesh)
		EndIf 
	End If 

	v0 = AddVertex(surf,x0,y0,z0) 
	v1 = AddVertex(surf,x1,y1,z1)  
	v2 = AddVertex(surf,(x0+x1)*0.5,(y0+y1)*0.5,(z0+z1)*0.5) 
	AddTriangle surf,v0,v1,v2 

	Return mesh 

End Function
PS: Nørd! Og du skal bruge [] firkantede paranteser i stedet for < > for at ramme din vilde kode ind :)


MadsNy(Posted 2004) [#22]
hehehe. thanks.. i will use [] instead of <> for code snipets..

Yes i figured out that i should try not to place all faces in the same surface......... and then it worked just fine... hehe so fine that i let it run for a while and had around 300'000 faces hehehe.. yep FPS went down quick.. hehe...
and as top of the cake it all loop with 130 surfaces and used clearsurface to clean up.... nicely. now i just have to make the lines fade put dynamic... :)

thanks.