// Persistence of Vision Ray Tracer Scene Description File // File: spline_tools.inc // Vers: 3.6 // Desc: tools for extruding a spline // Date: August 20, 2006 // Auth: Tim Attwood #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 #local rez = 1/L; #local shaperez = 1/W; mesh { #local loop1 = 0; #while (loop1<=(1-rez)) #local 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} #local loop2=loop2+shaperez; #end #local loop1=loop1+rez; #end } #end // creates a mesh by extruding Shape_Spline along Path_spline // and saves it to a file #macro Extrude_Spline_To_File(MeshName, Filename, 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 #fopen File Filename write #local rez = 1/L; #local shaperez = 1/W; #write (File, concat("#declare ",MeshName," = mesh {\n") ) #local loop1 = 0; #while (loop1<=(1-rez)) #local 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); #write (File, concat(" triangle {<", vstr(3, A, ",", 0,3),">,<", vstr(3, C, ",", 0,3),">,<", vstr(3, B, ",", 0,3),">}\n" ) ) #write (File, concat(" triangle {<", vstr(3, B, ",", 0,3),">,<", vstr(3, C, ",", 0,3),">,<", vstr(3, D, ",", 0,3),">}\n" ) ) #local loop2=loop2+shaperez; #end #local loop1=loop1+rez; #end #write (File, "};\n") #fclose File #end // example: //Spline_Translate(A_spline, "A_spline", -0.1, 1.1, 0.1, "natural_spline", <-35,0,0>) #macro Spline_Translate(SplA SplB begin_at stop_at rez stype vec) #fopen FOut "spline_tools.tmp" write #write (FOut, concat("#declare ",SplB," = spline {\n",stype,"\n") ) #local cin = begin_at; #while (cin <= stop_at) #local Temp = SplA(cin) + vec; #write(FOut,concat(str(cin,0,3),",<",vstr(3, Temp,",", 0,3),">\n") ) #local cin = cin + rez; #end #write (FOut, "};\n" ) #fclose FOut #include "spline_tools.tmp" #end #macro Spline_Rotate(SplA SplB begin_at stop_at rez stype vec) #fopen FOut "spline_tools.tmp" write #write (FOut, concat("#declare ",SplB," = spline {\n",stype,"\n") ) #local cin = begin_at; #while (cin <= stop_at) #local Temp = vrotate(SplA(cin),vec); #write(FOut,concat(str(cin,0,3),",<",vstr(3, Temp,",", 0,3),">\n") ) #local cin = cin + rez; #end #write (FOut, "};\n" ) #fclose FOut #include "spline_tools.tmp" #end #macro Spline_Scale(SplA SplB begin_at stop_at rez stype vec) #fopen FOut "spline_tools.tmp" write #write (FOut, concat("#declare ",SplB," = spline {\n",stype,"\n") ) #local cin = begin_at; #while (cin <= stop_at) #local Temp = ; #write(FOut,concat(str(cin,0,3),",<",vstr(3, Temp,",", 0,3),">\n") ) #local cin = cin + rez; #end #write (FOut, "};\n" ) #fclose FOut #include "spline_tools.tmp" #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