3D Lines

Blitz3D Forums/Blitz3D Programming/3D Lines

gosse(Posted 2005) [#1]
It makes a few times that I see people requesting code for 3D lines but I've never seen a good solution popping up.
Here's something I hacked today when someone asked it on CodersWorkshop.
Use CreateLine to create a new 3d line (with a wide range of parameters) and use UpdateLines in your main loop so the system can adjust them according to the camera.
Have fun with it! ;)
Const scrWidth = 640
Const scrHeight = 480
Graphics3D scrWidth, scrHeight, 0, 2
AmbientLight 255, 255, 255
AppTitle "3D Lines"
AntiAlias True
SeedRnd MilliSecs()

camDefault = CreateCamera()
CameraClsColor camDefault, 110, 220, 250
MoveEntity camDefault, 0, 5, 0

lgtDefault = CreateLight(2, camDefault)
LightRange lgtDefault, 5
MoveEntity lgtDefault, 0, 3, 0

mdlBall = CreateSphere()
MoveEntity mdlBall, 6, 2, 3
mdlCube = CreateCube()
MoveEntity mdlCube, 4, 3.5, 4
ScaleEntity mdlCube, 3.4, 0.3, 0.3
mdlCylinder = CreateCylinder()
ScaleEntity mdlCylinder, 1, 5, 1
EntityColor mdlCylinder, 255, 200, 50
EntityColor mdlCube, 6, 11, 19
EntityColor mdlBall, 255, 0, 100

mdlGround = CreatePlane(16)
EntityColor mdlGround, 50, 150, 50

Global FrameStart
Global DeltaTime# = 0.1
Global GameTime# = 0
Global FPS = 1200
Global FPSCount = FPS
Global timFPS

fntDefault = LoadFont("FixedSys", 24)
SetFont fntDefault

ln = createline(0, 10, 10, 8, 5, 10, camDefault)

CreateLine(2, 2, 2, 2, 2, 4, camDefault, 255, 255, 255, 1, 1, 1, 1, -1)
CreateLine(2, 2, 4, 4, 2, 4, camDefault, 255, 255, 255, 1, 1, 1, 1, -1)
CreateLine(4, 2, 4, 4, 2, 2, camDefault, 255, 255, 255, 1, 1, 1, 1, -1)
CreateLine(4, 2, 2, 2, 2, 2, camDefault, 255, 255, 255, 1, 1, 1, 1, -1)

CreateLine(2, 2, 2, 2, 4, 2, camDefault, 255, 255, 255, 1, 1, 1, 1, -1)
CreateLine(2, 2, 4, 2, 4, 4, camDefault, 255, 255, 255, 1, 1, 1, 1, -1)
CreateLine(4, 2, 4, 4, 4, 4, camDefault, 255, 255, 255, 1, 1, 1, 1, -1)
CreateLine(4, 2, 2, 4, 4, 2, camDefault, 255, 255, 255, 1, 1, 1, 1, -1)

CreateLine(2, 4, 2, 2, 4, 4, camDefault, 255, 255, 255, 1, 1, 1, 1, -1)
CreateLine(2, 4, 4, 4, 4, 4, camDefault, 255, 255, 255, 1, 1, 1, 1, -1)
CreateLine(4, 4, 4, 4, 4, 2, camDefault, 255, 255, 255, 1, 1, 1, 1, -1)
CreateLine(4, 4, 2, 2, 4, 2, camDefault, 255, 255, 255, 1, 1, 1, 1, -1)

For i = 0 To 100
	CreateLine(Rnd(0, 30) - 15, Rnd(0, 10), Rnd(0, 30) - 15, Rnd(0, 30) - 15, Rnd(0, 10), Rnd(0, 30) - 15, camDefault, Rand(0, 255), Rand(0, 255), Rand(0, 255), Rnd(0.2, 1), 1)
Next


While Not KeyDown(1)

	; Frame Update
	FrameStart = MilliSecs()
	If timFPS < FrameStart Then
		FPS = FPSCount
		FPSCount = 0
		timFPS = FrameStart + 1000
		DeltaTime = 1.0 / Float(FPS)
		GameTime = GameTime + DeltaTime
	End If
	
	; Movement
	mx# = KeyDown(203) - KeyDown(205)
	mx = mx * DeltaTime * 50
	mz# = KeyDown(200) - KeyDown(208)
	mz = mz * DeltaTime * 3
	MoveEntity camDefault, 0, 0, mz
	TurnEntity camDefault, 0, mx, 0
	
	UpdateLines()
		
	; 3D Drawing
	SetBuffer BackBuffer()
	Cls
	RenderWorld
	
	Text 1, 0, "FPS: " + FPS
	
	Flip False
	
	FPSCount = FPSCount + 1

Wend

Type Line3D
	Field x#[1], y#[1], z#[1]
	Field cam
	Field thick#
	Field mesh, sfc
	Field vertex
	Field pvt[2]
End Type

Function CreateLine(x1#, y1#, z1#, x2#, y2#, z2#, cam, r = 255, g = 255, b = 255, a# = 1, thick = 1, fx = 1, blend = 1, order = 0, zoom# = 1)
	Local l.Line3D = New Line3D
	l\x[0] = x1
	l\y[0] = y1
	l\z[0] = z1
	l\x[1] = x2
	l\y[1] = y2
	l\z[1] = z2
	l\cam = cam
	l\thick = Float(thick) / zoom
	l\mesh = CreateMesh()
	l\sfc = CreateSurface(l\mesh)
	EntityColor l\mesh, r, g, b
	EntityAlpha l\mesh, a
	EntityOrder l\mesh, order
	EntityFX l\mesh, fx
	EntityBlend l\mesh, blend
	l\vertex = AddVertex(l\sfc, x1, y1, z1)
	AddVertex(l\sfc, x2, y2, z2)
	AddVertex(l\sfc, x2, y2, z2)
	AddVertex(l\sfc, x1, y1, z1)
	AddTriangle(l\sfc, l\vertex, l\vertex+1, l\vertex+2)
	AddTriangle(l\sfc, l\vertex, l\vertex+2, l\vertex+3)
	AddTriangle(l\sfc, l\vertex+2, l\vertex+1, l\vertex)
	AddTriangle(l\sfc, l\vertex+3, l\vertex+2, l\vertex)
	AddTriangle(l\sfc, l\vertex+3, l\vertex, l\vertex+1)
	AddTriangle(l\sfc, l\vertex+3, l\vertex+1, l\vertex+2)
	l\pvt[0] = CreatePivot()
	PositionEntity l\pvt[0], x1, y1, z1
	l\pvt[1] = CreatePivot()
	PositionEntity l\pvt[1], x2, y2, z2
	l\pvt[2] = CreatePivot()
	Return Handle(l)
End Function

Function ChangeLine(ln, x1#, y1#, z1#, x2#, y2#, z2#, cam, r = 255, g = 255, b = 255, a# = 1, thick = 1, fx = 1, blend = 1, order = 0, zoom# = 1)
	Local l.Line3D = Object.Line3D(ln)
	l\x[0] = x1
	l\y[0] = y1
	l\z[0] = z1
	l\x[1] = x2
	l\y[1] = y2
	l\z[1] = z2
	l\cam = cam
	l\thick = Float(thick) / zoom
	EntityColor l\mesh, r, g, b
	EntityAlpha l\mesh, a
	EntityOrder l\mesh, order
	EntityFX l\mesh, fx
	EntityBlend l\mesh, blend
	PositionEntity l\pvt[0], x1, y1, z1
	PositionEntity l\pvt[1], x2, y2, z2
End Function

Function DeleteLine(ln)
	Local l.Line3D = Object.Line3D(ln)
	FreeEntity l\mesh
	Delete l
End Function

Function UpdateLines()
	Local x[1], y[1], r#, d#
	For l.Line3D = Each Line3D

		PositionEntity l\pvt[2], l\x[0], l\y[0], l\z[0]
		PointEntity l\pvt[2], l\pvt[1]
		r = VectorYaw(l\x[0] - EntityX(l\cam), 0, l\z[0] - EntityZ(l\cam))
		RotateEntity l\pvt[2], EntityPitch(l\pvt[2]), r-90, 0
		d = EntityDistance(l\cam, l\pvt[2]) * l\thick * 0.00125
		MoveEntity l\pvt[2], 0, -d, 0
		VertexCoords l\sfc, l\vertex, EntityX(l\pvt[2]), EntityY(l\pvt[2]), EntityZ(l\pvt[2])
		MoveEntity l\pvt[2], 0, d*2, 0
		VertexCoords l\sfc, l\vertex+3, EntityX(l\pvt[2]), EntityY(l\pvt[2]), EntityZ(l\pvt[2])

		PositionEntity l\pvt[2], l\x[1], l\y[1], l\z[1]
		PointEntity l\pvt[2], l\pvt[0]
		r = VectorYaw(l\x[1] - EntityX(l\cam), 0, l\z[1] - EntityZ(l\cam))
		RotateEntity l\pvt[2], EntityPitch(l\pvt[2]), r+90, 0
		d = EntityDistance(l\cam, l\pvt[2]) * l\thick * 0.00125
		MoveEntity l\pvt[2], 0, -d, 0
		VertexCoords l\sfc, l\vertex+1, EntityX(l\pvt[2]), EntityY(l\pvt[2]), EntityZ(l\pvt[2])
		MoveEntity l\pvt[2], 0, d*2, 0
		VertexCoords l\sfc, l\vertex+2, EntityX(l\pvt[2]), EntityY(l\pvt[2]), EntityZ(l\pvt[2])

	Next
End Function



jfk EO-11110(Posted 2005) [#2]
I think there already is a 3D Line function in the archives, it has even been "code snippet of the month". However, you may post your solution to the archives too, so it won't "sink". Thanks BTW.


nadia(Posted 2005) [#3]
great! very usefull, thanks for sharing :-)


zortzblatz(Posted 2005) [#4]
createcylinder(3)
then scaling and rotating appropriatly is another way to make 3d lines


nadia(Posted 2005) [#5]
zortzblatz: yup, that works too but you'll find you add quite a few lines of code to position the end points of your cylinder at a specific position, (usually done with the help of an additional pivot).