14
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]