der_ton@Posted: Thu Oct 07, 2004 9:17 am Post subject: :
Code: |
fn printfloat flt =
--maxscript doesn't provide a way to format float output that I know of. It seems that Doom3 does not understand the <x>e<y> notation of floats --if you plan to use this in your scripts, note that this function doesn't check against a large number passed in ( --if (abs flt)>10.0 then return flt -- this could be used to gain some speed. --else local numdigits = 10 ( str = "" if flt<0 then str += "-" flt2 = abs flt str += ((flt2 as integer) as string) flt2 -= (flt2 as integer) str +="." for i=1 to numdigits do ( flt2 *=10.0 str += ((flt2 as integer) as string) flt2 -= (flt2 as integer) if abs flt2 < (1/10^(numdigits-i+1)) then break ) return str ) ) |
Code: |
@version 2.0
@warnings @script generic exportfile = nil; // exportfile cam = nil; // cam that we are going to export (Camera Object Agent) forceDecimal: num { // Lscript will convert a decimal to scientific notation after 4 consecutive zeros. numDigits = 10; strOutput = ""; if (num<0) { strOutput += "-"; } num = abs(num); num2 = frac(num); num = num - num2; strOutput += string(num) + "."; for (i=1; i<=numDigits; i++) { num2 *= 10.0; strOutput += string(integer(num2)); num2 -= integer(num2); if (abs(num2) < (pow(1/10,(numDigits-i+1)))) { break; } } return strOutput; } exportmd5camera { scn = Scene(); s_fps = scn.fps; s_start = scn.previewstart; s_end = scn.previewend; exportfile.writeln("MD5Version 10"); exportfile.writeln("commandline \"\"\n"); exportfile.writeln("numFrames ", s_end-s_start+1); exportfile.writeln("frameRate ", s_fps); exportfile.writeln("numCuts 0\n"); exportfile.writeln("cuts {\n}\n"); exportfile.writeln("camera {\n"); for (i = s_start; i<=s_end; i++) { fovarray = cam.fovAngles(i/s_fps); rot=cam.getWorldRotation(i/s_fps); pos=cam.getWorldPosition(i/s_fps); // corrections based on 360 degree test camera rotations. /* For some reason, values over 180 or less than -180 caused the camera to switch directions. For instance, a 0 to 360 rotation around the heading would work fine until heading reaches a value of 181. At this point instead of continuing in a clockwise direction it would reverse direction. It behaves as if 181 is the same as 179. I'm guessing that values in the range of -180 to 180 are the only acceptable values? It's driving me nuts because those are the only values that work. Anyway, I've corrected that issue using the conditional statements below. This way whenever a value is beyond that range it is looped back around into it. The only problem is I'm not sure how to adjust the camera orientation now. The camera points east at 0,0,0 when 0,0,0 should point north. If I adjust the conditional statments affecting rot.x to compensate for this, I get really funky results. For instance, a rotation around the bank would result in a 270 degree rotation around pitch that then stops and then rotates 360 around the bank. I'm sure the reason I'm struggling with this is because I don't understand the math behind quaternions. If i did, I could adjust for the orientation after the quaternion calculations and maybe that would make a world of difference. */ rot=<rot.x, rot.y, rot.z>; // correct rot.x if (rot.x < -180) { rot.x += 360; } if (rot.x > 180) { rot.x -= 360; } // correct rot.y if (rot.y < -180) { rot.y += 360; } if (rot.y > 180) { rot.y -= 360; } // correct rot.z if (rot.z < -180) { rot.z += 360; } if (rot.z > 180) { rot.z -= 360; } pos_d3=<pos.x, pos.z, pos.y>; c1=cos(rot.x/360*PI); c2=cos(rot.y/360*PI); c3=cos(rot.z/360*PI); s1=sin(rot.x/360*PI); s2=sin(rot.y/360*PI); s3=sin(rot.z/360*PI); q1=s1*c2*c3-c1*s2*s3; //pitch q2=c1*s2*c3+s1*c2*s3; //bank q3=c1*c2*s3-s1*s2*c3; //heading // convert quaternions to strings so they can be written in decimal notation. v1=forceDecimal(q1); v2=forceDecimal(q2); v3=forceDecimal(q3); // User should set camera aspect ratio to 1:1 so that fovarray[1] and fovarray[2] are the same? exportfile.writeln("\t( ", pos_d3," ) ( ",v3, " ", v2, " ", v1, " ) ",fovarray[1]*180/PI); } exportfile.writeln("}"); } generic { scn = Scene(); userobj = scn.firstSelect(); if (userobj == nil || userobj.genus != CAMERA) { //no camera was selected, so we export the first in the scene if there is any userobj = Camera(); if (userobj == nil) { info ("No camera in the scene"); return; } } cam = userobj; exportfilename = getfile("Export File", "*.md5camera"); if(exportfilename == nil) return; exportfile = File(exportfilename,"w"); if(exportfile == nil) { error("Unable to get writing access to ",exportfilename); return; } exportmd5camera(); info("Export Complete"); } |
Code: |
@version 2.0
@warnings @script generic exportfile = nil; // exportfile cam = nil; // cam that we are going to export (Camera Object Agent) wrapValues: num { // takes values that exceed range and loops them back into valid values if (num < -180) { num += 360; } if (num > 180) { num -= 360; } return num; } forceDecimal: num { // Lscript will convert a decimal to scientific notation after 4 consecutive zeros. numDigits = 10; strOutput = ""; if (num<0) { strOutput += "-"; } num = abs(num); num2 = frac(num); num = num - num2; strOutput += string(num) + "."; for (i=1; i<=numDigits; i++) { num2 *= 10.0; strOutput += string(integer(num2)); num2 -= integer(num2); if (abs(num2) < (pow(1/10,(numDigits-i+1)))) { break; } } if (num2==0) { strOutput += "0000000000"; } return strOutput; } exportmd5camera { scn = Scene(); s_fps = scn.fps; s_start = scn.previewstart; s_end = scn.previewend; exportfile.writeln("MD5Version 10"); exportfile.writeln("commandline \"\"\n"); exportfile.writeln("numFrames ", s_end-s_start+1); exportfile.writeln("frameRate ", s_fps); exportfile.writeln("numCuts 0\n"); exportfile.writeln("cuts {\n}\n"); exportfile.writeln("camera {\n"); for (i = s_start; i<=s_end; i++) { fovarray = cam.fovAngles(i/s_fps); rot=cam.getWorldRotation(i/s_fps); pos=cam.getWorldPosition(i/s_fps); // swivel camera values and adjust heading orientation rot_d3=<rot.y, rot.z, rot.x - 90>; // wrap rotational values into range -180 to 180 rot_d3.x = wrapValues(rot_d3.x); rot_d3.y = wrapValues(rot_d3.y); rot_d3.z = wrapValues(rot_d3.z); pos_d3=<pos.x, pos.z, pos.y>; c1=cos(rot_d3.x/360*PI); c2=cos(rot_d3.y/360*PI); c3=cos(rot_d3.z/360*PI); s1=sin(rot_d3.x/360*PI); s2=sin(rot_d3.y/360*PI); s3=sin(rot_d3.z/360*PI); q1=s1*c2*c3-c1*s2*s3; q2=c1*s2*c3+s1*c2*s3; q3=c1*c2*s3-s1*s2*c3; // convert values to strings so they can be written in decimal notation v1=forceDecimal(pos_d3.x); v2=forceDecimal(pos_d3.y); v3=forceDecimal(pos_d3.z); v4=forceDecimal(q1); v5=forceDecimal(q2); v6=forceDecimal(q3); v7=forceDecimal(fovarray[1]*180/PI); // User should set camera aspect ratio to 1:1 so that fovarray[1] and fovarray[2] are the same? exportfile.writeln("\t( ", v1, " ", v2, " ", v3, " ) ( ", v4, " ", v5, " ", v6, " ) ", v7); } exportfile.writeln("}"); } generic { scn = Scene(); userobj = scn.firstSelect(); if (userobj == nil || userobj.genus != CAMERA) { //no camera was selected, so we export the first in the scene if there is any userobj = Camera(); if (userobj == nil) { info ("No camera in the scene"); return; } } cam = userobj; exportfilename = getfile("Export File", "*.md5camera"); if(exportfilename == nil) return; exportfile = File(exportfilename,"w"); if(exportfile == nil) { error("Unable to get writing access to ",exportfilename); return; } exportmd5camera(); info("Export Complete"); } |
Code: |
@version 2.0
@warnings @script generic exportfile = nil; // exportfile cam = nil; // cam that we are going to export (Camera Object Agent) numcuts = nil; // number of cuts cuts = nil; // array of cuts numframes = nil; // number of frames s_fps = nil; // frames per second s_start = nil; // starting frame s_end = nil; // ending frame wrapValues: num { // takes values that exceed range and loops them back into valid values if (num < -180) { num += 360; } if (num > 180) { num -= 360; } return num; } forceDecimal: num { // Lscript will convert a decimal to scientific notation after 4 consecutive zeros. numDigits = 10; strOutput = ""; if (num<0) { strOutput += "-"; } num = abs(num); num2 = frac(num); num = num - num2; strOutput += string(num) + "."; for (i=1; i<=numDigits; i++) { num2 *= 10.0; strOutput += string(integer(num2)); num2 -= integer(num2); if (abs(num2) < (pow(1/10,(numDigits-i+1)))) { break; } } if (num2==0) { strOutput += "0000000000"; } return strOutput; } exportmd5camera { exportfile.writeln("MD5Version 10"); exportfile.writeln("commandline \"\"\n"); exportfile.writeln("numFrames ", numframes); exportfile.writeln("frameRate ", s_fps); exportfile.writeln("numCuts "+ numcuts + "\n"); exportfile.writeln("cuts {"); for (i = 1; i<=numcuts; i++) { exportfile.writeln(cuts[i]); } exportfile.writeln("}\n"); exportfile.writeln("camera {\n"); for (i = s_start; i<=s_end; i++) { fovarray = cam.fovAngles(i/s_fps); rot=cam.getWorldRotation(i/s_fps); pos=cam.getWorldPosition(i/s_fps); // swivel camera values and adjust heading orientation rot_d3=<rot.y, rot.z, rot.x - 90>; // wrap rotational values into range -180 to 180 rot_d3.x = wrapValues(rot_d3.x); rot_d3.y = wrapValues(rot_d3.y); rot_d3.z = wrapValues(rot_d3.z); pos_d3=<pos.x, pos.z, pos.y>; c1=cos(rot_d3.x/360*PI); c2=cos(rot_d3.y/360*PI); c3=cos(rot_d3.z/360*PI); s1=sin(rot_d3.x/360*PI); s2=sin(rot_d3.y/360*PI); s3=sin(rot_d3.z/360*PI); q1=s1*c2*c3-c1*s2*s3; q2=c1*s2*c3+s1*c2*s3; q3=c1*c2*s3-s1*s2*c3; // convert values to strings so they can be written in decimal notation v1=forceDecimal(pos_d3.x); v2=forceDecimal(pos_d3.y); v3=forceDecimal(pos_d3.z); v4=forceDecimal(q1); v5=forceDecimal(q2); v6=forceDecimal(q3); v7=forceDecimal(fovarray[1]*180/PI); // User should set camera aspect ratio to 1:1 so that fovarray[1] and fovarray[2] are the same? exportfile.writeln("\t( ", v1, " ", v2, " ", v3, " ) ( ", v4, " ", v5, " ", v6, " ) ", v7); } exportfile.writeln("}"); } toggleOff: value { return(false); } generic { // get info for requestor scn = Scene(); userobj = scn.firstSelect(); if (userobj == nil || userobj.genus != CAMERA) { //no camera was selected, so we export the first in the scene if there is any userobj = Camera(); if (userobj == nil) { info ("No camera in the scene"); return; } } cam = userobj; cutlist = ""; exportfilename = ""; s_fps = scn.fps; s_start = scn.previewstart; s_end = scn.previewend; numframes = s_end - s_start + 1; // display requester reqbegin("Lightwave MD5camera Exporter"); reqsize(492,155); c1 = ctlinteger("Frame Rate",s_fps); ctlposition(c1,361,12); c2 = ctlstring("Cut List",cutlist); ctlposition(c2,10,73,476,18); c3 = ctlfilename("Save As",exportfilename); ctlposition(c3,5,104,458,19); c4 = ctlinteger("Start Frame",s_start); ctlposition(c4,85,42); c5 = ctlinteger("End Frame",s_end); ctlposition(c5,225,42); c6 = ctlinteger("Total Frames",numframes); ctlposition(c6,355,42); c7 = ctlcameraitems("Camera",cam); ctlposition(c7,3,11,343,19); // deactivate all unmodifiable controls ctlactive(c3, "toggleOff", c1, c4, c5, c6); return if !reqpost(); s_fps = getvalue(c1); cutlist = getvalue(c2); exportfilename = getvalue(c3); s_start = getvalue(c4); s_end = getvalue(c5); numframes = getvalue(c6); cam = getvalue(c7); reqend(); // validate values and setup file for output if(cam == nil) { error ("No camera selected"); return; } if(cutlist == nil) { numcuts = 0; } else { cuts = parse(";",cutlist); numcuts = size(cuts); //info(string(numcuts) + " cuts were found"); for (i=1; i<=numcuts; i++) { test = integer(cuts[i]); if (test == nil) { error(cuts[i]+" is not an integer"); return; } else { cuts[i] = test - s_start; } //error(cuts[i]+" is not an integer"); if (integer(cuts[i]) < s_start or integer(cuts[i]) > s_end) { error(cuts[i]+" is out of range"); return; } } } exportfile = File(exportfilename,"w"); if(exportfile == nil) { error("Unable to get writing access to ",exportfilename); return; } exportmd5camera(); info("Export Complete"); } |
Code: |
10;20 |
Code: |
MD5Version 10 // Header and Version
commandline "" // Command Line Parameters - Used to convert maya format numFrames 452 // The Number of Frames frameRate 24 // The Framerate numCuts 3 // The Number of Cuts cuts { // A List of Frames Where Cuts Take Place 110 329 429 } camera { // A List of Key Frames ( -908.6940917969 -3417.0383300781 552.0170898438 ) ( -0.0069773775 0.0820536837 -0.084440738 ) 54.4321250916 ... // The format for each line is as follows... continues on // (X_POS, Y_POS, Z_POS) (HEADING, PITCH, BANK) FOV ... ( -903.4814453125 -3417.0383300781 555.6039428711 ) ( -0.0068133976 0.0792509392 -0.0853850618 ) 54.4321250916 } |
Code: |
LWMO
3 NumChannels 6 Channel 0 // X channel { Envelope 1 // Number of keys in this channel Key 1 0 0 0 0 0 0 0 0 // Keys (Value, Time, Incoming Curve, Tension, Continuity, Bias, NA, NA, NA) Behaviors 1 1 // Pre and Post Behavior (0-Reset, 1-Constant, 2-Repeat, 3-Oscillate, 4-Offset Repeat, 5-Linear) } Channel 1 // Y channel { Envelope 1 Key 2 0 0 0 0 0 0 0 0 Behaviors 1 1 } Channel 2 // Z channel { Envelope 1 Key 3 0 0 0 0 0 0 0 0 Behaviors 1 1 } Channel 3 // Heading channel { Envelope 1 Key 0.06981317 0 0 0 0 0 0 0 0 Behaviors 1 1 } Channel 4 // Pitch Channel { Envelope 1 Key 0.08726646 0 0 0 0 0 0 0 0 Behaviors 1 1 } Channel 5 // Bank Channel { Envelope 1 Key 0.10471975 0 0 0 0 0 0 0 0 Behaviors 1 1 } |
Code: |
Qx = [ cos(a/2), (sin(a/2), 0, 0)]
Qy = [ cos(b/2), (0, sin(b/2), 0)] Qz = [ cos(c/2), (0, 0, sin(c/2))] |
Code: |
a = 90
b = 180 c = 270 |
Code: |
Qx = [ cos(90/2), (sin(90/2), 0, 0)]
Qy = [ cos(180/2), (0, sin(180/2), 0)] Qz = [ cos(270/2), (0, 0, sin(270/2))] |
Code: |
Qx = [ cos(45), (sin(45), 0, 0)]
Qy = [ cos(90), (0, sin(90), 0)] Qz = [ cos(135), (0, 0, sin(135))] |
Code: |
Qx = [ 0.70710678118654752440084436210485, (0.70710678118654752440084436210485, 0, 0)]
Qy = [ 0, (0, 1, 0)] Qz = [ -0.70710678118654752440084436210485, (0, 0, 0.70710678118654752440084436210485)] |
Code: |
Qw = Qx * Qy * Qz |
Code: |
Q1 * Q2 =( w1.w2 - v1.v2, w1.v2 + w2.v1 + v1*v2) |
Code: |
Qw = (Qx * Qy) * Qz |
Quote: |
Be aware that the order of multiplication is important. Quaternion multiplication is not commutative, meaning
q1 * q2 does not equal q2 * q1 |
Code: |
Channel 3
{ Envelope 2 Key 0 0 0 0 0 0 0 0 0 Key 1.5707963 2.5 0 0 0 0 1.5706217 0 0 Behaviors 1 1 } Channel 4 { Envelope 2 Key 0 0 0 0 0 0 0 0 0 Key 3.1415925 2.5 0 0 0 0 3.1412435 0 0 Behaviors 1 1 } Channel 5 { Envelope 2 Key 0 0 0 0 0 0 0 0 0 Key 4.712389 2.5 0 0 0 0 4.7118654 0 0 Behaviors 1 1 } |
Quote: |
Envelopes
An envelope defines a function of time. For any animation time, an envelope's parameters can be combined to generate a value at that time. Envelopes are used to store position coordinates, rotation angles, scale factors, camera zoom, light intensity, texture parameters, and anything else that can vary over time. The envelope function is a piecewise polynomial curve. The function is tabulated at specific points, called keys. The curve segment between two adjacent keys is called a span, and values on the span are calculated by interpolating between the keys. The interpolation can be linear, cubic, or stepped, and it can be different for each span. The value of the function before the first key and after the last key is calculated by extrapolation. In scene files, an envelope is stored in a block named Envelope that contains one or more nested Key blocks and one Behaviors block. { Envelope nkeys Key value time spantype p1 p2 p3 p4 p5 p6 Key ... Behaviors pre post } The nkeys value is an integer, the number of Key blocks in the envelope. Envelopes must contain at least one Key block. The contents of a Key block are as follows. value The key value, a floating-point number. The units and limits of the value depend on what parameter the envelope represents. time The time in seconds, a float. This can be negative, zero or positive. Keys are listed in the envelope in increasing time order. spantype The curve type, an integer. This determines the kind of interpolation that will be performed on the span between this key and the previous key, and also indicates what interpolation parameters are stored for the key. 0 - TCB (Kochanek-Bartels) 1 - Hermite 2 - 1D Bezier (obsolete, equivalent to Hermite) 3 - Linear 4 - Stepped 5 - 2D Bezier p1...p6 Curve parameters. The data depends on the span type. TCB, Hermite, 1D Bezier The first three parameters are tension, continuity and bias. The fourth and fifth parameters are the incoming and outgoing tangents. The sixth parameter is ignored and should be 0. Use the first three to evaluate TCB spans, and the other two to evaluate Hermite spans. 2D Bezier The first two parameters are the incoming time and value, and the second two are the outgoing time and value. The Behaviors block contains two integers. pre, post Pre- and post-behaviors. These determine how the envelope is extrapolated at times before the first key and after the last one. 0 - Reset Sets the value to 0.0. 1 - Constant Sets the value to the value at the nearest key. 2 - Repeat Repeats the interval between the first and last keys (the primary interval). 3 - Oscillate Like Repeat, but alternating copies of the primary interval are time-reversed. 4 - Offset Repeat Like Repeat, but offset by the difference between the values of the first and last keys. 5 - Linear Linearly extrapolates the value based on the tangent at the nearest key. |
der_ton wrote: |
So the value is "3.1415925" where it should be 180? Hmm, let me think why this number seems familiar... These are radians. Convert between degrees and radians with these formulae: deg = rad * 180 / PI rad = deg * PI / 180 |
Code: |
@version 2.0 @warnings @script generic exportfile = nil; // exportfile cam = nil; // camera that we are going to export (Camera Object Agent) exportmd5camera { exportfile.writeln("name ", cam.name, "\n"); for (i = 1; i<=10; i++) { fovarray = cam.fovAngles(i); exportfile.writeln("pos ", cam.getPosition(i)); exportfile.writeln("rot ", cam.getRotation(i)); exportfile.writeln("fov ", fovarray[1], " ", fovarray[2], "\n"); } } generic { scn = Scene(); userobj = scn.firstSelect(); if (userobj == nil || userobj.genus != CAMERA) { //no camera was selected, so we export the first in the scene if there is any userobj = Camera(); if (userobj == nil) { info ("No camera in the scene"); return; } } cam = userobj; exportfilename = getfile("Export File", "*.md5camera"); if(exportfilename == nil) return; exportfile = File(exportfilename,"w"); if(exportfile == nil) { error("Unable to open ",exportfilename); return; } exportmd5camera(); } |
Code: |
name Camera
pos 0 0 -1.99997 rot 0 0 0 fov 0.789582 0.60577 pos 0 0 -4.00005 rot 0 0 0 fov 0.789582 0.60577 pos 0 0 -5 rot 0 0 0 fov 0.789582 0.60577 pos 0 0 -5 rot 0 0 0 fov 0.789582 0.60577 pos 0 0 -5 rot 0 0 0 fov 0.789582 0.60577 ... continues |
Code: |
for (i = 0; i<=10; i++)
{ fovarray = cam.fovAngles(i); exportfile.writeln("pos ", cam.getPosition(i)); exportfile.writeln("rot ", cam.getRotation(i)); exportfile.writeln("fov ", fovarray[1], " ", fovarray[2], "\n"); } |
Code: |
@version 2.0 @warnings @script generic exportfile = nil; // exportfile cam = nil; // camera that we are going to export (Camera Object Agent) exportmd5camera { // Get the fps, starting, and ending frames from the scene. scn = Scene(); s_fps = scn.fps; s_start = scn.framestart; s_end = scn.frameend; exportfile.writeln("name ", cam.name, "\n"); count = s_start; i = 0; while (count <= s_end){ i = count / s_fps; // Increment the time according to the fps. exportfile.writeln("frame ", count); exportfile.writeln("time ", i); fovarray = cam.fovAngles(i); exportfile.writeln("pos ", cam.getPosition(i)); exportfile.writeln("rot ", cam.getRotation(i)); exportfile.writeln("fov ", fovarray[1], " ", fovarray[2], "\n"); count++; } } generic { scn = Scene(); userobj = scn.firstSelect(); if (userobj == nil || userobj.genus != CAMERA) { //no camera was selected, so we export the first in the scene if there is any userobj = Camera(); if (userobj == nil) { info ("No camera in the scene"); return; } } cam = userobj; exportfilename = getfile("Export File", "*.md5camera"); if(exportfilename == nil) return; exportfile = File(exportfilename,"w"); if(exportfile == nil) { error("Unable to open ",exportfilename); return; } exportmd5camera(); } |
Code: |
@version 2.0
@warnings @script generic exportfile = nil; // exportfile cam = nil; // cam that we are going to export (Camera Object Agent) exportmd5camera { scn = Scene(); s_fps = scn.fps; s_start = scn.framestart; s_end = scn.frameend; exportfile.writeln("MD5Version 10"); exportfile.writeln("commandline \"\"\n"); exportfile.writeln("numFrames ", s_end-s_start+1); exportfile.writeln("frameRate ", s_fps); exportfile.writeln("numCuts 0\n"); exportfile.writeln("cuts {\n}\n"); exportfile.writeln("camera {\n"); for (i = s_start; i<=s_end; i++) { fovarray = cam.fovAngles(i/s_fps); rot=cam.getRotation(i/s_fps); pos=cam.getPosition(i/s_fps); pos_d3=<pos.x, pos.z, pos.y>; c1=cos(rot.x/360*PI); c2=cos(rot.y/360*PI); c3=cos(rot.z/360*PI); s1=sin(rot.x/360*PI); s2=sin(rot.y/360*PI); s3=sin(rot.z/360*PI); q1=s1*c2*c3-c1*s2*s3; q2=c1*s2*c3+s1*c2*s3; q3=c1*c2*s3-s1*s2*c3; exportfile.writeln("\t( ", pos_d3," ) ( ",q1, " ", q2, " ", q3, " ) ",fovarray[1]*180/PI); //maybe fovarray[2] (vertical fov) should be used? } exportfile.writeln("}"); } generic { scn = Scene(); userobj = scn.firstSelect(); if (userobj == nil || userobj.genus != CAMERA) { //no camera was selected, so we export the first in the scene if there is any userobj = Camera(); if (userobj == nil) { info ("No camera in the scene"); return; } } cam = userobj; exportfilename = getfile("Export File", "*.md5camera"); if(exportfilename == nil) return; exportfile = File(exportfilename,"w"); if(exportfile == nil) { error("Unable to get writing access to ",exportfilename); return; } exportmd5camera(); } |
Code: |
@version 2.0
@warnings @script generic exportfile = nil; // exportfile cam = nil; // cam that we are going to export (Camera Object Agent) exportmd5camera { scn = Scene(); s_fps = scn.fps; s_start = scn.framestart; s_end = scn.frameend; exportfile.writeln("MD5Version 10"); exportfile.writeln("commandline \"\"\n"); exportfile.writeln("numFrames ", s_end-s_start+1); exportfile.writeln("frameRate ", s_fps); exportfile.writeln("numCuts 0\n"); exportfile.writeln("cuts {\n}\n"); exportfile.writeln("camera {\n"); for (i = s_start; i<=s_end; i++) { fovarray = cam.fovAngles(i/s_fps); rot=cam.getRotation(i/s_fps); pos=cam.getPosition(i/s_fps); pos_d3=<pos.x, pos.z, pos.y>; c1=cos(rot.x/360*PI); c2=cos(rot.y/360*PI); c3=cos(rot.z/360*PI); s1=sin(rot.x/360*PI); s2=sin(rot.y/360*PI); s3=sin(rot.z/360*PI); q1=s1*c2*c3-c1*s2*s3; //bank q2=c1*s2*c3+s1*c2*s3; //pitch q3=c1*c2*s3-s1*s2*c3; //heading // invert q2 because it rotates up when it should look down q2=q2*-1; // User should set camera aspect ratio to 1:1 so that fovarray[1] and fovarray[2] are the same? exportfile.writeln("\t( ", pos_d3," ) ( ",q3, " ", q2, " ", q1, " ) ",fovarray[1]*180/PI); } exportfile.writeln("}"); } generic { scn = Scene(); userobj = scn.firstSelect(); if (userobj == nil || userobj.genus != CAMERA) { //no camera was selected, so we export the first in the scene if there is any userobj = Camera(); if (userobj == nil) { info ("No camera in the scene"); return; } } cam = userobj; exportfilename = getfile("Export File", "*.md5camera"); if(exportfilename == nil) return; exportfile = File(exportfilename,"w"); if(exportfile == nil) { error("Unable to get writing access to ",exportfilename); return; } exportmd5camera(); } |
Code: |
scn = Scene();
s_fps = scn.fps; s_start = scn.framestart; s_end = scn.frameend; |
Code: |
MD5Version 10 // Header and Version
commandline "" // Command Line Parameters - Used to convert maya format numFrames 452 // The Number of Frames frameRate 24 // The Framerate numCuts 3 // The Number of Cuts cuts { // A List of Frames Where Cuts Take Place 110 329 429 } camera { // A List of Key Frames ( -908.6940917969 -3417.0383300781 552.0170898438 ) ( -0.0069773775 0.0820536837 -0.084440738 ) 54.4321250916 ... // The format for each line is as follows... continues on // (X_POS, Y_POS, Z_POS) (HEADING, PITCH, BANK) FOV ... ( -903.4814453125 -3417.0383300781 555.6039428711 ) ( -0.0068133976 0.0792509392 -0.0853850618 ) 54.4321250916 } |
Code: |
LWMO
3 NumChannels 6 Channel 0 // X channel { Envelope 1 // Number of keys in this channel Key 1 0 0 0 0 0 0 0 0 // Keys (Value, Time, Incoming Curve, Tension, Continuity, Bias, NA, NA, NA) Behaviors 1 1 // Pre and Post Behavior (0-Reset, 1-Constant, 2-Repeat, 3-Oscillate, 4-Offset Repeat, 5-Linear) } Channel 1 // Y channel { Envelope 1 Key 2 0 0 0 0 0 0 0 0 Behaviors 1 1 } Channel 2 // Z channel { Envelope 1 Key 3 0 0 0 0 0 0 0 0 Behaviors 1 1 } Channel 3 // Heading channel { Envelope 1 Key 0.06981317 0 0 0 0 0 0 0 0 Behaviors 1 1 } Channel 4 // Pitch Channel { Envelope 1 Key 0.08726646 0 0 0 0 0 0 0 0 Behaviors 1 1 } Channel 5 // Bank Channel { Envelope 1 Key 0.10471975 0 0 0 0 0 0 0 0 Behaviors 1 1 } |
Code: |
Qx = [ cos(a/2), (sin(a/2), 0, 0)]
Qy = [ cos(b/2), (0, sin(b/2), 0)] Qz = [ cos(c/2), (0, 0, sin(c/2))] |
Code: |
a = 90
b = 180 c = 270 |
Code: |
Qx = [ cos(90/2), (sin(90/2), 0, 0)]
Qy = [ cos(180/2), (0, sin(180/2), 0)] Qz = [ cos(270/2), (0, 0, sin(270/2))] |
Code: |
Qx = [ cos(45), (sin(45), 0, 0)]
Qy = [ cos(90), (0, sin(90), 0)] Qz = [ cos(135), (0, 0, sin(135))] |
Code: |
Qx = [ 0.70710678118654752440084436210485, (0.70710678118654752440084436210485, 0, 0)]
Qy = [ 0, (0, 1, 0)] Qz = [ -0.70710678118654752440084436210485, (0, 0, 0.70710678118654752440084436210485)] |
Code: |
Qw = Qx * Qy * Qz |
Code: |
Q1 * Q2 =( w1.w2 - v1.v2, w1.v2 + w2.v1 + v1*v2) |
Code: |
Qw = (Qx * Qy) * Qz |
Quote: |
Be aware that the order of multiplication is important. Quaternion multiplication is not commutative, meaning
q1 * q2 does not equal q2 * q1 |
Code: |
Channel 3
{ Envelope 2 Key 0 0 0 0 0 0 0 0 0 Key 1.5707963 2.5 0 0 0 0 1.5706217 0 0 Behaviors 1 1 } Channel 4 { Envelope 2 Key 0 0 0 0 0 0 0 0 0 Key 3.1415925 2.5 0 0 0 0 3.1412435 0 0 Behaviors 1 1 } Channel 5 { Envelope 2 Key 0 0 0 0 0 0 0 0 0 Key 4.712389 2.5 0 0 0 0 4.7118654 0 0 Behaviors 1 1 } |
Quote: |
Envelopes
An envelope defines a function of time. For any animation time, an envelope's parameters can be combined to generate a value at that time. Envelopes are used to store position coordinates, rotation angles, scale factors, camera zoom, light intensity, texture parameters, and anything else that can vary over time. The envelope function is a piecewise polynomial curve. The function is tabulated at specific points, called keys. The curve segment between two adjacent keys is called a span, and values on the span are calculated by interpolating between the keys. The interpolation can be linear, cubic, or stepped, and it can be different for each span. The value of the function before the first key and after the last key is calculated by extrapolation. In scene files, an envelope is stored in a block named Envelope that contains one or more nested Key blocks and one Behaviors block. { Envelope nkeys Key value time spantype p1 p2 p3 p4 p5 p6 Key ... Behaviors pre post } The nkeys value is an integer, the number of Key blocks in the envelope. Envelopes must contain at least one Key block. The contents of a Key block are as follows. value The key value, a floating-point number. The units and limits of the value depend on what parameter the envelope represents. time The time in seconds, a float. This can be negative, zero or positive. Keys are listed in the envelope in increasing time order. spantype The curve type, an integer. This determines the kind of interpolation that will be performed on the span between this key and the previous key, and also indicates what interpolation parameters are stored for the key. 0 - TCB (Kochanek-Bartels) 1 - Hermite 2 - 1D Bezier (obsolete, equivalent to Hermite) 3 - Linear 4 - Stepped 5 - 2D Bezier p1...p6 Curve parameters. The data depends on the span type. TCB, Hermite, 1D Bezier The first three parameters are tension, continuity and bias. The fourth and fifth parameters are the incoming and outgoing tangents. The sixth parameter is ignored and should be 0. Use the first three to evaluate TCB spans, and the other two to evaluate Hermite spans. 2D Bezier The first two parameters are the incoming time and value, and the second two are the outgoing time and value. The Behaviors block contains two integers. pre, post Pre- and post-behaviors. These determine how the envelope is extrapolated at times before the first key and after the last one. 0 - Reset Sets the value to 0.0. 1 - Constant Sets the value to the value at the nearest key. 2 - Repeat Repeats the interval between the first and last keys (the primary interval). 3 - Oscillate Like Repeat, but alternating copies of the primary interval are time-reversed. 4 - Offset Repeat Like Repeat, but offset by the difference between the values of the first and last keys. 5 - Linear Linearly extrapolates the value based on the tangent at the nearest key. |
der_ton wrote: |
So the value is "3.1415925" where it should be 180? Hmm, let me think why this number seems familiar... These are radians. Convert between degrees and radians with these formulae: deg = rad * 180 / PI rad = deg * PI / 180 |
Code: |
@version 2.0 @warnings @script generic exportfile = nil; // exportfile cam = nil; // camera that we are going to export (Camera Object Agent) exportmd5camera { exportfile.writeln("name ", cam.name, "\n"); for (i = 1; i<=10; i++) { fovarray = cam.fovAngles(i); exportfile.writeln("pos ", cam.getPosition(i)); exportfile.writeln("rot ", cam.getRotation(i)); exportfile.writeln("fov ", fovarray[1], " ", fovarray[2], "\n"); } } generic { scn = Scene(); userobj = scn.firstSelect(); if (userobj == nil || userobj.genus != CAMERA) { //no camera was selected, so we export the first in the scene if there is any userobj = Camera(); if (userobj == nil) { info ("No camera in the scene"); return; } } cam = userobj; exportfilename = getfile("Export File", "*.md5camera"); if(exportfilename == nil) return; exportfile = File(exportfilename,"w"); if(exportfile == nil) { error("Unable to open ",exportfilename); return; } exportmd5camera(); } |
Code: |
name Camera
pos 0 0 -1.99997 rot 0 0 0 fov 0.789582 0.60577 pos 0 0 -4.00005 rot 0 0 0 fov 0.789582 0.60577 pos 0 0 -5 rot 0 0 0 fov 0.789582 0.60577 pos 0 0 -5 rot 0 0 0 fov 0.789582 0.60577 pos 0 0 -5 rot 0 0 0 fov 0.789582 0.60577 ... continues |
Code: |
for (i = 0; i<=10; i++)
{ fovarray = cam.fovAngles(i); exportfile.writeln("pos ", cam.getPosition(i)); exportfile.writeln("rot ", cam.getRotation(i)); exportfile.writeln("fov ", fovarray[1], " ", fovarray[2], "\n"); } |
Code: |
@version 2.0 @warnings @script generic exportfile = nil; // exportfile cam = nil; // camera that we are going to export (Camera Object Agent) exportmd5camera { // Get the fps, starting, and ending frames from the scene. scn = Scene(); s_fps = scn.fps; s_start = scn.framestart; s_end = scn.frameend; exportfile.writeln("name ", cam.name, "\n"); count = s_start; i = 0; while (count <= s_end){ i = count / s_fps; // Increment the time according to the fps. exportfile.writeln("frame ", count); exportfile.writeln("time ", i); fovarray = cam.fovAngles(i); exportfile.writeln("pos ", cam.getPosition(i)); exportfile.writeln("rot ", cam.getRotation(i)); exportfile.writeln("fov ", fovarray[1], " ", fovarray[2], "\n"); count++; } } generic { scn = Scene(); userobj = scn.firstSelect(); if (userobj == nil || userobj.genus != CAMERA) { //no camera was selected, so we export the first in the scene if there is any userobj = Camera(); if (userobj == nil) { info ("No camera in the scene"); return; } } cam = userobj; exportfilename = getfile("Export File", "*.md5camera"); if(exportfilename == nil) return; exportfile = File(exportfilename,"w"); if(exportfile == nil) { error("Unable to open ",exportfilename); return; } exportmd5camera(); } |
Code: |
@version 2.0
@warnings @script generic exportfile = nil; // exportfile cam = nil; // cam that we are going to export (Camera Object Agent) exportmd5camera { scn = Scene(); s_fps = scn.fps; s_start = scn.framestart; s_end = scn.frameend; exportfile.writeln("MD5Version 10"); exportfile.writeln("commandline \"\"\n"); exportfile.writeln("numFrames ", s_end-s_start+1); exportfile.writeln("frameRate ", s_fps); exportfile.writeln("numCuts 0\n"); exportfile.writeln("cuts {\n}\n"); exportfile.writeln("camera {\n"); for (i = s_start; i<=s_end; i++) { fovarray = cam.fovAngles(i/s_fps); rot=cam.getRotation(i/s_fps); pos=cam.getPosition(i/s_fps); pos_d3=<pos.x, pos.z, pos.y>; c1=cos(rot.x/360*PI); c2=cos(rot.y/360*PI); c3=cos(rot.z/360*PI); s1=sin(rot.x/360*PI); s2=sin(rot.y/360*PI); s3=sin(rot.z/360*PI); q1=s1*c2*c3-c1*s2*s3; q2=c1*s2*c3+s1*c2*s3; q3=c1*c2*s3-s1*s2*c3; exportfile.writeln("\t( ", pos_d3," ) ( ",q1, " ", q2, " ", q3, " ) ",fovarray[1]*180/PI); //maybe fovarray[2] (vertical fov) should be used? } exportfile.writeln("}"); } generic { scn = Scene(); userobj = scn.firstSelect(); if (userobj == nil || userobj.genus != CAMERA) { //no camera was selected, so we export the first in the scene if there is any userobj = Camera(); if (userobj == nil) { info ("No camera in the scene"); return; } } cam = userobj; exportfilename = getfile("Export File", "*.md5camera"); if(exportfilename == nil) return; exportfile = File(exportfilename,"w"); if(exportfile == nil) { error("Unable to get writing access to ",exportfilename); return; } exportmd5camera(); } |
Code: |
@version 2.0
@warnings @script generic exportfile = nil; // exportfile cam = nil; // cam that we are going to export (Camera Object Agent) exportmd5camera { scn = Scene(); s_fps = scn.fps; s_start = scn.framestart; s_end = scn.frameend; exportfile.writeln("MD5Version 10"); exportfile.writeln("commandline \"\"\n"); exportfile.writeln("numFrames ", s_end-s_start+1); exportfile.writeln("frameRate ", s_fps); exportfile.writeln("numCuts 0\n"); exportfile.writeln("cuts {\n}\n"); exportfile.writeln("camera {\n"); for (i = s_start; i<=s_end; i++) { fovarray = cam.fovAngles(i/s_fps); rot=cam.getRotation(i/s_fps); pos=cam.getPosition(i/s_fps); pos_d3=<pos.x, pos.z, pos.y>; c1=cos(rot.x/360*PI); c2=cos(rot.y/360*PI); c3=cos(rot.z/360*PI); s1=sin(rot.x/360*PI); s2=sin(rot.y/360*PI); s3=sin(rot.z/360*PI); q1=s1*c2*c3-c1*s2*s3; //bank q2=c1*s2*c3+s1*c2*s3; //pitch q3=c1*c2*s3-s1*s2*c3; //heading // invert q2 because it rotates up when it should look down q2=q2*-1; // User should set camera aspect ratio to 1:1 so that fovarray[1] and fovarray[2] are the same? exportfile.writeln("\t( ", pos_d3," ) ( ",q3, " ", q2, " ", q1, " ) ",fovarray[1]*180/PI); } exportfile.writeln("}"); } generic { scn = Scene(); userobj = scn.firstSelect(); if (userobj == nil || userobj.genus != CAMERA) { //no camera was selected, so we export the first in the scene if there is any userobj = Camera(); if (userobj == nil) { info ("No camera in the scene"); return; } } cam = userobj; exportfilename = getfile("Export File", "*.md5camera"); if(exportfilename == nil) return; exportfile = File(exportfilename,"w"); if(exportfile == nil) { error("Unable to get writing access to ",exportfilename); return; } exportmd5camera(); } |
Code: |
scn = Scene();
s_fps = scn.fps; s_start = scn.framestart; s_end = scn.frameend; |
Code: |
fn printfloat flt =
--maxscript doesn't provide a way to format float output that I know of. It seems that Doom3 does not understand the <x>e<y> notation of floats --if you plan to use this in your scripts, note that this function doesn't check against a large number passed in ( --if (abs flt)>10.0 then return flt -- this could be used to gain some speed. --else local numdigits = 10 ( str = "" if flt<0 then str += "-" flt2 = abs flt str += ((flt2 as integer) as string) flt2 -= (flt2 as integer) str +="." for i=1 to numdigits do ( flt2 *=10.0 str += ((flt2 as integer) as string) flt2 -= (flt2 as integer) if abs flt2 < (1/10^(numdigits-i+1)) then break ) return str ) ) |
Code: |
@version 2.0
@warnings @script generic exportfile = nil; // exportfile cam = nil; // cam that we are going to export (Camera Object Agent) forceDecimal: num { // Lscript will convert a decimal to scientific notation after 4 consecutive zeros. numDigits = 10; strOutput = ""; if (num<0) { strOutput += "-"; } num = abs(num); num2 = frac(num); num = num - num2; strOutput += string(num) + "."; for (i=1; i<=numDigits; i++) { num2 *= 10.0; strOutput += string(integer(num2)); num2 -= integer(num2); if (abs(num2) < (pow(1/10,(numDigits-i+1)))) { break; } } return strOutput; } exportmd5camera { scn = Scene(); s_fps = scn.fps; s_start = scn.previewstart; s_end = scn.previewend; exportfile.writeln("MD5Version 10"); exportfile.writeln("commandline \"\"\n"); exportfile.writeln("numFrames ", s_end-s_start+1); exportfile.writeln("frameRate ", s_fps); exportfile.writeln("numCuts 0\n"); exportfile.writeln("cuts {\n}\n"); exportfile.writeln("camera {\n"); for (i = s_start; i<=s_end; i++) { fovarray = cam.fovAngles(i/s_fps); rot=cam.getWorldRotation(i/s_fps); pos=cam.getWorldPosition(i/s_fps); // corrections based on 360 degree test camera rotations. /* For some reason, values over 180 or less than -180 caused the camera to switch directions. For instance, a 0 to 360 rotation around the heading would work fine until heading reaches a value of 181. At this point instead of continuing in a clockwise direction it would reverse direction. It behaves as if 181 is the same as 179. I'm guessing that values in the range of -180 to 180 are the only acceptable values? It's driving me nuts because those are the only values that work. Anyway, I've corrected that issue using the conditional statements below. This way whenever a value is beyond that range it is looped back around into it. The only problem is I'm not sure how to adjust the camera orientation now. The camera points east at 0,0,0 when 0,0,0 should point north. If I adjust the conditional statments affecting rot.x to compensate for this, I get really funky results. For instance, a rotation around the bank would result in a 270 degree rotation around pitch that then stops and then rotates 360 around the bank. I'm sure the reason I'm struggling with this is because I don't understand the math behind quaternions. If i did, I could adjust for the orientation after the quaternion calculations and maybe that would make a world of difference. */ rot=<rot.x, rot.y, rot.z>; // correct rot.x if (rot.x < -180) { rot.x += 360; } if (rot.x > 180) { rot.x -= 360; } // correct rot.y if (rot.y < -180) { rot.y += 360; } if (rot.y > 180) { rot.y -= 360; } // correct rot.z if (rot.z < -180) { rot.z += 360; } if (rot.z > 180) { rot.z -= 360; } pos_d3=<pos.x, pos.z, pos.y>; c1=cos(rot.x/360*PI); c2=cos(rot.y/360*PI); c3=cos(rot.z/360*PI); s1=sin(rot.x/360*PI); s2=sin(rot.y/360*PI); s3=sin(rot.z/360*PI); q1=s1*c2*c3-c1*s2*s3; //pitch q2=c1*s2*c3+s1*c2*s3; //bank q3=c1*c2*s3-s1*s2*c3; //heading // convert quaternions to strings so they can be written in decimal notation. v1=forceDecimal(q1); v2=forceDecimal(q2); v3=forceDecimal(q3); // User should set camera aspect ratio to 1:1 so that fovarray[1] and fovarray[2] are the same? exportfile.writeln("\t( ", pos_d3," ) ( ",v3, " ", v2, " ", v1, " ) ",fovarray[1]*180/PI); } exportfile.writeln("}"); } generic { scn = Scene(); userobj = scn.firstSelect(); if (userobj == nil || userobj.genus != CAMERA) { //no camera was selected, so we export the first in the scene if there is any userobj = Camera(); if (userobj == nil) { info ("No camera in the scene"); return; } } cam = userobj; exportfilename = getfile("Export File", "*.md5camera"); if(exportfilename == nil) return; exportfile = File(exportfilename,"w"); if(exportfile == nil) { error("Unable to get writing access to ",exportfilename); return; } exportmd5camera(); info("Export Complete"); } |
Code: |
@version 2.0
@warnings @script generic exportfile = nil; // exportfile cam = nil; // cam that we are going to export (Camera Object Agent) wrapValues: num { // takes values that exceed range and loops them back into valid values if (num < -180) { num += 360; } if (num > 180) { num -= 360; } return num; } forceDecimal: num { // Lscript will convert a decimal to scientific notation after 4 consecutive zeros. numDigits = 10; strOutput = ""; if (num<0) { strOutput += "-"; } num = abs(num); num2 = frac(num); num = num - num2; strOutput += string(num) + "."; for (i=1; i<=numDigits; i++) { num2 *= 10.0; strOutput += string(integer(num2)); num2 -= integer(num2); if (abs(num2) < (pow(1/10,(numDigits-i+1)))) { break; } } if (num2==0) { strOutput += "0000000000"; } return strOutput; } exportmd5camera { scn = Scene(); s_fps = scn.fps; s_start = scn.previewstart; s_end = scn.previewend; exportfile.writeln("MD5Version 10"); exportfile.writeln("commandline \"\"\n"); exportfile.writeln("numFrames ", s_end-s_start+1); exportfile.writeln("frameRate ", s_fps); exportfile.writeln("numCuts 0\n"); exportfile.writeln("cuts {\n}\n"); exportfile.writeln("camera {\n"); for (i = s_start; i<=s_end; i++) { fovarray = cam.fovAngles(i/s_fps); rot=cam.getWorldRotation(i/s_fps); pos=cam.getWorldPosition(i/s_fps); // swivel camera values and adjust heading orientation rot_d3=<rot.y, rot.z, rot.x - 90>; // wrap rotational values into range -180 to 180 rot_d3.x = wrapValues(rot_d3.x); rot_d3.y = wrapValues(rot_d3.y); rot_d3.z = wrapValues(rot_d3.z); pos_d3=<pos.x, pos.z, pos.y>; c1=cos(rot_d3.x/360*PI); c2=cos(rot_d3.y/360*PI); c3=cos(rot_d3.z/360*PI); s1=sin(rot_d3.x/360*PI); s2=sin(rot_d3.y/360*PI); s3=sin(rot_d3.z/360*PI); q1=s1*c2*c3-c1*s2*s3; q2=c1*s2*c3+s1*c2*s3; q3=c1*c2*s3-s1*s2*c3; // convert values to strings so they can be written in decimal notation v1=forceDecimal(pos_d3.x); v2=forceDecimal(pos_d3.y); v3=forceDecimal(pos_d3.z); v4=forceDecimal(q1); v5=forceDecimal(q2); v6=forceDecimal(q3); v7=forceDecimal(fovarray[1]*180/PI); // User should set camera aspect ratio to 1:1 so that fovarray[1] and fovarray[2] are the same? exportfile.writeln("\t( ", v1, " ", v2, " ", v3, " ) ( ", v4, " ", v5, " ", v6, " ) ", v7); } exportfile.writeln("}"); } generic { scn = Scene(); userobj = scn.firstSelect(); if (userobj == nil || userobj.genus != CAMERA) { //no camera was selected, so we export the first in the scene if there is any userobj = Camera(); if (userobj == nil) { info ("No camera in the scene"); return; } } cam = userobj; exportfilename = getfile("Export File", "*.md5camera"); if(exportfilename == nil) return; exportfile = File(exportfilename,"w"); if(exportfile == nil) { error("Unable to get writing access to ",exportfilename); return; } exportmd5camera(); info("Export Complete"); } |
Code: |
@version 2.0
@warnings @script generic exportfile = nil; // exportfile cam = nil; // cam that we are going to export (Camera Object Agent) numcuts = nil; // number of cuts cuts = nil; // array of cuts numframes = nil; // number of frames s_fps = nil; // frames per second s_start = nil; // starting frame s_end = nil; // ending frame wrapValues: num { // takes values that exceed range and loops them back into valid values if (num < -180) { num += 360; } if (num > 180) { num -= 360; } return num; } forceDecimal: num { // Lscript will convert a decimal to scientific notation after 4 consecutive zeros. numDigits = 10; strOutput = ""; if (num<0) { strOutput += "-"; } num = abs(num); num2 = frac(num); num = num - num2; strOutput += string(num) + "."; for (i=1; i<=numDigits; i++) { num2 *= 10.0; strOutput += string(integer(num2)); num2 -= integer(num2); if (abs(num2) < (pow(1/10,(numDigits-i+1)))) { break; } } if (num2==0) { strOutput += "0000000000"; } return strOutput; } exportmd5camera { exportfile.writeln("MD5Version 10"); exportfile.writeln("commandline \"\"\n"); exportfile.writeln("numFrames ", numframes); exportfile.writeln("frameRate ", s_fps); exportfile.writeln("numCuts "+ numcuts + "\n"); exportfile.writeln("cuts {"); for (i = 1; i<=numcuts; i++) { exportfile.writeln(cuts[i]); } exportfile.writeln("}\n"); exportfile.writeln("camera {\n"); for (i = s_start; i<=s_end; i++) { fovarray = cam.fovAngles(i/s_fps); rot=cam.getWorldRotation(i/s_fps); pos=cam.getWorldPosition(i/s_fps); // swivel camera values and adjust heading orientation rot_d3=<rot.y, rot.z, rot.x - 90>; // wrap rotational values into range -180 to 180 rot_d3.x = wrapValues(rot_d3.x); rot_d3.y = wrapValues(rot_d3.y); rot_d3.z = wrapValues(rot_d3.z); pos_d3=<pos.x, pos.z, pos.y>; c1=cos(rot_d3.x/360*PI); c2=cos(rot_d3.y/360*PI); c3=cos(rot_d3.z/360*PI); s1=sin(rot_d3.x/360*PI); s2=sin(rot_d3.y/360*PI); s3=sin(rot_d3.z/360*PI); q1=s1*c2*c3-c1*s2*s3; q2=c1*s2*c3+s1*c2*s3; q3=c1*c2*s3-s1*s2*c3; // convert values to strings so they can be written in decimal notation v1=forceDecimal(pos_d3.x); v2=forceDecimal(pos_d3.y); v3=forceDecimal(pos_d3.z); v4=forceDecimal(q1); v5=forceDecimal(q2); v6=forceDecimal(q3); v7=forceDecimal(fovarray[1]*180/PI); // User should set camera aspect ratio to 1:1 so that fovarray[1] and fovarray[2] are the same? exportfile.writeln("\t( ", v1, " ", v2, " ", v3, " ) ( ", v4, " ", v5, " ", v6, " ) ", v7); } exportfile.writeln("}"); } toggleOff: value { return(false); } generic { // get info for requestor scn = Scene(); userobj = scn.firstSelect(); if (userobj == nil || userobj.genus != CAMERA) { //no camera was selected, so we export the first in the scene if there is any userobj = Camera(); if (userobj == nil) { info ("No camera in the scene"); return; } } cam = userobj; cutlist = ""; exportfilename = ""; s_fps = scn.fps; s_start = scn.previewstart; s_end = scn.previewend; numframes = s_end - s_start + 1; // display requester reqbegin("Lightwave MD5camera Exporter"); reqsize(492,155); c1 = ctlinteger("Frame Rate",s_fps); ctlposition(c1,361,12); c2 = ctlstring("Cut List",cutlist); ctlposition(c2,10,73,476,18); c3 = ctlfilename("Save As",exportfilename); ctlposition(c3,5,104,458,19); c4 = ctlinteger("Start Frame",s_start); ctlposition(c4,85,42); c5 = ctlinteger("End Frame",s_end); ctlposition(c5,225,42); c6 = ctlinteger("Total Frames",numframes); ctlposition(c6,355,42); c7 = ctlcameraitems("Camera",cam); ctlposition(c7,3,11,343,19); // deactivate all unmodifiable controls ctlactive(c3, "toggleOff", c1, c4, c5, c6); return if !reqpost(); s_fps = getvalue(c1); cutlist = getvalue(c2); exportfilename = getvalue(c3); s_start = getvalue(c4); s_end = getvalue(c5); numframes = getvalue(c6); cam = getvalue(c7); reqend(); // validate values and setup file for output if(cam == nil) { error ("No camera selected"); return; } if(cutlist == nil) { numcuts = 0; } else { cuts = parse(";",cutlist); numcuts = size(cuts); //info(string(numcuts) + " cuts were found"); for (i=1; i<=numcuts; i++) { test = integer(cuts[i]); if (test == nil) { error(cuts[i]+" is not an integer"); return; } else { cuts[i] = test - s_start; } //error(cuts[i]+" is not an integer"); if (integer(cuts[i]) < s_start or integer(cuts[i]) > s_end) { error(cuts[i]+" is out of range"); return; } } } exportfile = File(exportfilename,"w"); if(exportfile == nil) { error("Unable to get writing access to ",exportfilename); return; } exportmd5camera(); info("Export Complete"); } |
Code: |
10;20 |