I took on the challenge to make a 3D splined path editor, to test out my new GLBasic skills, and I got a reasonable demo working.

However I have run into a brick wall with the QuadraticBezier3d, Not the function itself, that works brilliantly, but I'm rather stuck on how to make a continuous spline that runs through all 4 points that I use. The idea is to increase the key points on request, and generate splines as required. But alas my skills have dried up at this point.

I use the Bezier curves library from Hemlos to do the splines, but I am missing something along the way.

Any guidance will be most welcome

I've made certain arrays Global in the library in order to access them in my program.

Here's the program so far.

`//SETCURRENTDIR("Media")`

//LOADFONT "..smalfont.png", 1

//SETFONT 1

TYPE POINT

x#

y#

z#

ENDTYPE

GLOBAL points[] AS POINT

GLOBAL splines[] AS POINT

GLOBAL waypoints[] AS POINT

GLOBAL numPoints = 4 //Key points for generating bezier curve points

GLOBAL extent# = 300 //Set pixel graph size: 100 means from -100 to +100. Change to desired path scale

GLOBAL CALC = FALSE

GLOBAL maxPoints = 30 //Bexier points: MUST be divisable by 2, else the calculations will fall over

LOCAL keyPoint = 0 //current key point

LOCAL i

LOCAL steps#

LOCAL angle = 270

LOCAL UpAngle = 0

LOCAL distanceP# = 2.5

LOCAL help = 1

SetupPoints()

WHILE TRUE

IF KEY(203) THEN angle = angle - 1 //left arrow

IF KEY(205) THEN angle = angle + 1 //right arrow

IF KEY(200) THEN UpAngle = UpAngle +1 //up arrow

IF KEY(208) THEN UpAngle = UpAngle -1 //down arrow

IF KEY(59) THEN help = -help; WHILE KEY(59); WEND //F1

IF KEY(15) THEN keyPoint = keyPoint+1;WHILE KEY(15); WEND //Tab

IF keyPoint > numPoints-1 THEN keyPoint = 0

IF KEY(17) //W

INC points[keyPoint].z

CALC = FALSE

ENDIF

IF KEY(31) //S

DEC points[keyPoint].z

CALC = FALSE

ENDIF

IF KEY(30) //A

INC points[keyPoint].x //Reverse this if you prefer

CALC = FALSE

ENDIF

IF KEY(32) //D

DEC points[keyPoint].x //Reverse this if you prefer

CALC = FALSE

ENDIF

IF KEY(19) //R

INC points[keyPoint].y

CALC = FALSE

ENDIF

IF KEY(33) //F

DEC points[keyPoint].y

CALC = FALSE

ENDIF

X_MAKE3D 1, 10000, 45

X_CAMERA COS(angle)*extent*distanceP, SIN(UpAngle)*extent*distanceP, SIN(angle)*extent*distanceP, 0, 0, 0

//grid

steps = extent*2/20

FOR i = -extent TO extent STEP steps

// XY grid

X_LINE -extent,i,0, extent,i,0, 0.1, RGB(0,0,60)

X_LINE i,-extent,0, i,extent,0, 0.1, RGB(0,0,60)

// XZ grid

X_LINE -extent,0,i, extent,0,i, 0.1, RGB(60,0,0)

X_LINE i,0,-extent, i,0,extent, 0.1, RGB(60,0,0)

//YX grid

X_LINE 0,-extent,i, 0,extent,i, 0.1, RGB(0,60,0)

X_LINE 0,i,-extent, 0,i,extent, 0.1, RGB(0,60,0)

NEXT

//z=0 indicator

X_LINE 0,0,0, 0,0,extent, 3, RGB(255,0,0)

//draw points

FOR i = 0 TO numPoints-1

IF i <> keyPoint

X_DOT points[i].x, points[i].y, points[i].z,10, RGB(0,255,0) //10=size of keypoint: change as required

ENDIF

NEXT

//draw current key point

X_DOT points[keyPoint].x, points[keyPoint].y, points[keyPoint].z,10, RGB(255,0,255) //10=size of keypoint: change as required

BuildSplineArray()

//draw all spline points

FOR i = 0 TO LEN(splines)-1

X_DOT splines[i].x, splines[i].y, splines[i].z, 1, RGB(180,180,180)

NEXT

//Screen instructions

X_MAKE2D

PRINT "F1: Toggle help", 5,5, RGB(200,200,200)

IF help = 1

PRINT "LEFT ARROW: Rotate Left", 5,25,RGB(200,200,200)

PRINT "RIGHT ARROW: Rotate Right", 5,45,RGB(200,200,200)

PRINT "UP ARROW: Rotate Up", 5,65,RGB(200,200,200)

PRINT "DOWN ARROW: Rotate Down", 5,85,RGB(200,200,200)

PRINT "1: Add Key Point", 5,105,RGB(200,200,200)

PRINT "2: Remove Key Point", 5,125,RGB(200,200,200)

PRINT "TAB: Next Key Point",5,145,RGB(200,200,200)

PRINT "W: Move Z+", 5,165,RGB(200,200,200)

PRINT "S: Move Z-",5,185,RGB(200,200,200)

PRINT "A: Move X-",5,205,RGB(200,200,200)

PRINT "D: Move X+",5,225,RGB(200,200,200)

PRINT "R: Move Y+",5,245,RGB(200,200,200)

PRINT "F: Move Y-",5,265,RGB(200,200,200)

ENDIF

PRINT "Number of Key Points: "+numPoints, 5,580, RGB(200,200,200)

SHOWSCREEN

WEND

FUNCTION SetupPoints:

LOCAL point AS POINT

point.x = -extent/2; point.y=0; point.z=0; DIMPUSH points[],point

point.x = 0; point.y=-extent/2; point.z=0; DIMPUSH points[],point

point.x = extent/2; point.y=0; point.z=0; DIMPUSH points[],point

point.x = 0; point.y=extent/2; point.z=0; DIMPUSH points[],point

ENDFUNCTION

FUNCTION BuildSplineArray:

LOCAL i,j,n,m,mhf,tx,ty,tz

LOCAL spline AS POINT

IF CALC THEN RETURN

CALC = TRUE

//Empty the spline array for new spline points

FOR i = 0 TO LEN(splines)-1

DIMDEL splines[],0

NEXT

//Empty the waypoint array for new waypoints

FOR i = 0 TO LEN(waypoints)-1

DIMDEL waypoints[],0

NEXT

//build new spline array

i= -1

WHILE TRUE

//DEBUG i + "\n"

i = i+1

IF i <= numPoints - 3

QuadraticBezier3d(points[i].x, points[i].y, points[i].z, _

points[i+1].x, points[i+1].y, points[i+1].z, _

points[i+2].x, points[i+2].y, points[i+2].z, _

maxPoints)

FOR j = 0 TO LEN(QuadraticBezierArray3d) -1

spline.x = QuadraticBezierArray3d[j][0]

spline.y = QuadraticBezierArray3d[j][1]

spline.z = QuadraticBezierArray3d[j][2]

DIMPUSH splines[],spline

NEXT

ENDIF

IF i = numPoints -2

QuadraticBezier3d(points[i].x, points[i].y, points[i].z, _

points[i+1].x, points[i+1].y, points[i+1].z, _

points[0].x, points[0].y, points[0].z, _

maxPoints)

FOR j = 0 TO LEN(QuadraticBezierArray3d) -1

spline.x = QuadraticBezierArray3d[j][0]

spline.y = QuadraticBezierArray3d[j][1]

spline.z = QuadraticBezierArray3d[j][2]

DIMPUSH splines[],spline

NEXT

ENDIF

IF i = numPoints -1

QuadraticBezier3d(points[i].x, points[i].y, points[i].z, _

points[0].x, points[0].y, points[0].z, _

points[1].x, points[1].y, points[1].z, _

maxPoints)

FOR j = 0 TO LEN(QuadraticBezierArray3d) -1

spline.x = QuadraticBezierArray3d[j][0]

spline.y = QuadraticBezierArray3d[j][1]

spline.z = QuadraticBezierArray3d[j][2]

DIMPUSH splines[],spline

NEXT

ENDIF

IF i = numPoints THEN BREAK

WEND

ENDFUNCTION

The full project is attached as well

[attachment deleted by admin]