#ifndef(SPLINE_TOOLS_TEMP) #declare SPLINE_TOOLS_TEMP = version; //#version 3.6 #ifndef(STRINGS_INC_TEMP) #include "strings.inc" #end #ifndef(TRANSFORMS_INC_TEMP) #include "transforms.inc" #end // returns a spline that is a section of another spline #macro Split_Spline(SplA SplB begin_at stop_at rez stype) #local Split = concat("#declare ",SplB," = spline {\n",stype,"\n"); #local c = -rez; #while (c <= 1+rez) #local Split = concat(Split,str(c,1,3),",<", vstr(3, SplA(c * (stop_at - begin_at) + begin_at), ",", 0,3),">\n"); #local c = c + rez; #end #local Split = concat(Split,"};\n"); Parse_String(Split) #end // calculate the length of a spline #macro Len_Spline(Espl begin_at stop_at num) #local c = 1/num; #local V1 = Espl(begin_at); #local result = 0; #while (c <= 1) #local V2 = Espl( c*(stop_at - begin_at) + begin_at); #local result = result + vlength(V2-V1); #local V1 = V2; #local c = c + 1/num; #end (result) #end // saves a spline to a file #macro Save_Spline(SplA SplB Filename begin_at stop_at rez stype) #fopen FOut2 Filename write #write (FOut2, concat("#declare ",SplB," = spline {\n",stype,"\n") ) #local cin = begin_at; #while (cin <= stop_at) //Parse_String(concat("#declare A = ", SplB, "(",str(cin,0,-1),");\n") // SplA(cin) #write(FOut2,concat(str(cin,0,3),",<",vstr(3, SplA(cin), ",", 0,3),">\n") ) #local cin = cin + rez; #end #write (FOut2, "};\n" ) #fclose FOut2 #end // remap spline #macro Remap_Spline(SplA SplB begin_at stop_at rez stype begin_out stop_out) #local outrez = (stop_out - begin_out)/((stop_at - begin_at)/rez); #fopen FOut "spline_tools.tmp" write #write (FOut, concat("#declare ",SplB," = spline {\n",stype,"\n") ) #local cin = begin_at; #local cout = begin_out; #while (cin <= stop_at) #write(FOut,concat(str(cout,0,3),",<",vstr(3, SplA(cin),",", 0,3),">\n") ) #local cout = cout + outrez; #local cin = cin + rez; #end #write (FOut, "};\n" ) #fclose FOut #include "spline_tools.tmp" #end // transforms a vector by a matrix #macro VMatrix_Trans(vec, A, B, C, D) #local fn = function { transform { matrix < A.x, A.y, A.z, B.x, B.y, B.z, C.x, C.y, C.z, D.x, D.y, D.z> } } #local result = (fn(vec.x, vec.y, vec.z)); (result) #end // transforms a vector along Path_Spline #macro VSpline_Trans_Path (Vect, Time, Sky, Foresight, Banking) #ifndef (Path_Spline) #error "VSpline_Trans_Path requires Path_Spline to be #declared!\n" #end #local Location = <0,0,0>+Path_Spline(Time); #local LocationNext = <0,0,0>+Path_Spline(Time+Foresight); #local LocationPrev = <0,0,0>+Path_Spline(Time-Foresight); #local Forward = vnormalize(LocationNext-Location); #local Right = VPerp_To_Plane(Sky,Forward); #local Up = VPerp_To_Plane(Forward,Right); #local BankingRotation = degrees(atan2( VRotation( VProject_Plane((LocationNext-Location),Sky), VProject_Plane((Location-LocationPrev),Sky), Up )*Banking ,1 )); #local result = vrotate(Vect, BankingRotation*z); #local result = VMatrix_Trans(result,Right,Up,Forward,Location); (result) #end // creates a mesh by extruding Shape_Spline along Path_spline #macro Extrude_Spline(W, L, Sky, Foresight, Banking) #ifndef (Path_Spline) #error "Extrude_Spline requires Path_Spline to be #declared!\n" #end #ifndef (Shape_Spline) #error "Extrude_Spline requires Shape_Spline to be #declared!\n" #end #declare rez = 1/L; #declare shaperez = 1/W; mesh { #declare loop1 = 0; #while (loop1<=(1-rez)) #declare loop2 = 0; #while (loop2<=(1-shaperez)) #local A = VSpline_Trans_Path(Shape_Spline(loop2), loop1, Sky, Foresight, Banking); #local B = VSpline_Trans_Path(Shape_Spline(loop2+shaperez), loop1, Sky, Foresight, Banking); #local C = VSpline_Trans_Path(Shape_Spline(loop2), loop1+rez, Sky, Foresight, Banking); #local D = VSpline_Trans_Path(Shape_Spline(loop2+shaperez), loop1+rez, Sky, Foresight, Banking); triangle {A, C, B} triangle {B, C, D} #declare loop2=loop2+shaperez; #end #declare loop1=loop1+rez; #end } #end /* // repeated calls will use excessive memory for copies of splines #macro VSpline_Trans (Vect, Spline, Time, Sky, Foresight, Banking) #local Location = <0,0,0>+Spline(Time); #local LocationNext = <0,0,0>+Spline(Time+Foresight); #local LocationPrev = <0,0,0>+Spline(Time-Foresight); #local Forward = vnormalize(LocationNext-Location); #local Right = VPerp_To_Plane(Sky,Forward); #local Up = VPerp_To_Plane(Forward,Right); #local BankingRotation = degrees(atan2( VRotation( VProject_Plane((LocationNext-Location),Sky), VProject_Plane((Location-LocationPrev),Sky), Up )*Banking ,1 )); #local result = vrotate(Vect, BankingRotation*z); #local result = VMatrix_Trans(result,Right,Up,Forward,Location); (result) #end */ #end // spline tools