3D Lines

Blitz3D Forums/Blitz3D Programming/3D Lines

The forum is locked. These are the original blitzbasic.com forums, kept so they can still be read. No new topics, replies or edits can be made here. To join in, head over to the Blitz3D+ forums.

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