home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format 20
/
af020.adf
/
Script4D
/
readme.doc
< prev
next >
Wrap
Text File
|
1980-02-23
|
26KB
|
1,017 lines
********************************************************
DOCUMENTATION FOR AMIGA SCRIPT4D version 1.00 Jan 1991
Version 1.00 of the SCRIPT4D executable program is in the Public
Domain. It may be freely copied and distributed provided that it
is always accompanied by this document in it's original form and by
the supplied example files.
Bug reports, comments, suggested enhancements and constructive critisism
of SCRIPT4D are most welcome - BY MAIL - to:
Richard Swingwood
181 Bergholt Road
Colchester
Essex CO4 5AH
England
SCRIPT4D was developed using Lattice C V5.05.
If I've used any trademarks in this document then I acknowledge that
they belong to someone.
===================================================================
INTRODUCTION
===================================================================
SCRIPT4D was created to ease the pain of creating animated sequences
using the SCULPT 3D/4D range of software.
I don't wish to imply that those packages are, in themselves, the
cause of any grief. Personally, I find them a pleasure to use when
creating objects and scenes; the problem, for me, comes when doing
key-frame animations of any complexity. It's a chore I can do
without.
What I envisaged was a method of taking my ideas about HOW & WHEN
objects in a particular scene should move and have them converted
into a SCULPT script file that would do the hard work for me.
Assuming my ideas could be expressed in some sort of consise language
then, if I made a pigs ear of the animation, rather than have to wade
through umpteen key-frame scenes recalculating object positions and
making changes I could simply change my definition of the motions -
the AMIGA could then do the hard work!
I haven't forgotten about the global animation facility in SCULPT,
which can also take a lot of the hassle out of animation; I just
find it unusable for complex motions that are not repetitive.
As it happens, SCRIPT4D could well be put to other uses because it is
not tied to SCULPT command syntax or file formats.
So here's SCRIPT4D. It's by no means perfect or complete - I
need your feedback!
==================================================================
CONCEPTS
==================================================================
SCRIPT4D takes a 'scripting program' (program from now on) as input
an produces a file of SCUPLT script commands (script from now on) as
output. The script is then used to drive SCULPT and produce the
animation.
It is executed from the CLI with a command of the form:
SCRIPT4D <progname >scriptname
eg.
SCRIPT4D <Eye.prog >Eye.script
A program has a basic layout of:
FRAMES n
...declarations...
...procedures...
...controllers...
END
The 'FRAMES n' specifies the number of frames in the animation.
Declarations are used to define arrays of values and 'smooth motion'
information.
Procedures generally contain, amongst other things, SCULPT script
commands that will be ouptut to the script. Individual procedures
can be either active or suspended.
Controllers specify program actions to take place at specified
frames in the sequence. Controllers are usually used to activate
procedures at the required frames.
Program execution occurs as follows:
1) An internal current-frame counter is set to 1
2) Any and all controllers that refer to the current
frame are executed.
3) All active procedures are executed in the order
they appear in the program.
4) The frame counter is incremented and, if it does not
exceed the declared number of frames, execution
continues at 2) above.
A skeleton program would be..
FRAMES 50
TO blink /* procedure */
...commands...
END
TO nod /* procedure */
...commands...
END
AT 1 /* controller */
START nod
END
AT 5 25 /* controller */
START blink
END
END
Thus the procedure 'nod' would be activated just before frame 1 and 'blink'
would be activated just before frames 5 and 25.
Each time they would remain active until explicitly suspended, either
by itself, by another procedure or by a controller.
Let's take a more detailed look at a procedure. As we'll see later
this one will be used to make a modelled eye blink. The commands
used will be more fully described in the COMMANDS section.
TO blink
SETUP
blinkstep = 2 /* cos step 1 is 0 deg. */
closingtime = 0
END
EXECUTE
/* select next angle for smooth motion */
SMOOTH blinker blinkstep blinkangle
'DESELECT ALL'
'SELECT NAMED "Eye+Lid" ' /* script commands to.. */
'WINDOW EAST' /* rotate the eyelid... */
'ROTATE CLOCKWISE %d ' (i) blinkangle
IF blinkstep = 7 /* handle eye-closed time */
FREEZE closingtime
ENDIF
blinkstep += 1
IF blinkstep > 12
SUSPEND blink 32000 /* ie. until reSTARTed */
ENDIF
END
END
A procedure consists of two command blocks, SETUP & EXECUTE.
Commands in the SETUP block are executed at the time the procedure is
STARTed. Those in the EXECUTE block execute for each frame that the
procedure is active.
In our example the SETUP block is simply initializing two variables:
'blinkstep' is used to keep track of how far through the 'blink' we
are, 'closingtime' will be used to keep the eye closed for a
variable amount of time (zero extra frames by default.)
Once 'blink' is active, the commands in the EXECUTE block are executed
for each subsequent frame. The SMOOTH command will calculate a
suitable angle through which the eyelid should be rotated at the
current step in the blink. The necessary SCULPT script commands are
then output. Once the eye is closed, at step 7, it is 'frozen' in
that state for a variable number of frames, otherwise the step number
is incremented. If the blink has completed then the procedure
SUSPENDs itself.
Note that SCRIPT4D still relies on you to specify the appropriate
SCULPT script commands, but it then gives you flexible & programmable
control over the content & occurrence of those commands in the output
script.
==================================================================
EXAMPLE PROGRAM
==================================================================
For the purposes of this description, I'll assume we want to animate
a blinking eye that floats up & down. This in itself isn't complex
enough to warrant using SCRIPT4D but it provides a method of
demonstrating how SCRIPT4D can be used.
The approach we'll take is thus:
a) The animation will be 50 frames
b) A Take, named EYE has been created, all relevant
options selected and details filled in.
c) A global SCENE containing OBSERVER, TARGET & LAMP(S)
has been defined for the Take.
d) An scene, called EYEEYE, has been created and stored to
disk. The scene contains a single object.
This object is named as follows:
...Lid
|
Eye...|
|
|...Ball
|
|
|...Socket
The centre of the eye sits at (0,0,0) and it is looking
south. The eyelid covers the top of the eyeball, tilted
back about 45 degrees. The socket is simply a cube in
which the eye sits.
e) A scene will be created for every frame of the animation
by loading in the 'base' Eyeeye object and then modifying
it as required for that frame.
All the relevant files should accompany this program. I suggest you
have a quick peek at EYEEYE.SCENE so you can see what's what!
Every frame of the Take will be a key-frame. With the computer doing
the work there's no reason why not! In any case, with complex
animations this usually needs to be the case.
The program, listed below can be found in the file 'Eye.prog'.
Use this to generate the script file with the command:
SCRIPT4D <Eye.prog >Eye.script
Path names, both in the above command & in the supplied 'Take'
may need modifying depending on your system configuration.
There is a certain amount of 'housekeeping' required in the program,
resulting in something that appears too complicated for what we're
trying to achieve. However, such housekeeping can be defined once in
a 'template' program and subsequently reused (with minor changes.)
Note that within the program comments are delimited by '/*' & '*/'.
FRAMES 50
/* define a 7-step smooth motion for 0 thru 90 degrees */
SMOOTHER blinking 0 90 7
/* relative up/down motion in 10 steps */
SMOOTHER floating -400 400 10
TO init
EXECUTE
'LOAD TAKE "EYE" '
SUSPEND init 32000 /* init suspended for 32000 frames! */
END
END
TO getscene /* gets base scene for each frame */
EXECUTE
'TAKE CURRENT FRAME %d' (i) frame
'ERASE ALL'
'(0,0,0)'
'LOAD SCENE "Eyeeye.scene"'
END
END
TO blink /* how to make the eye blink */
SETUP
blinkstep = 2 /* 2 'cos 1st angle would be 0 */
closingtime = 0
END
EXECUTE
/* select next angle for smooth motion */
blinkangle @= blinking blinkstep /* alternative to SMOOTH */
'DESELECT ALL' /* output script commands to.. */
'SELECT NAMED "Eye+Lid"' /* ..rotate eyelid */
'WINDOW EAST'
'ROTATE CLOCKWISE %d' (i) blinkangle
IF blinkstep = 7 /* handle eye-closed time */
FREEZE closingtime
ENDIF
blinkstep += 1 /* ready for next frame */
IF blinkstep > 12
SUSPEND blink
ENDIF
END
END
TO float /* floating up & down */
SETUP floatstep = 1 END
EXECUTE
floatlevel @= floating floatstep
'SELECT ALL'
'GRABBER ON'
'[0,0,%d]' (i) floatlevel
'GRABBER OFF'
floatstep += 1
IF floatstep > 10
floatstep = 1
ENDIF
END
END
TO savescene /* saves scene & makes key frame */
EXECUTE
'TAKE KEY YES'
'TAKE SAVE KEY FRAME SCENE'
END
END
TO render /* final script command */
EXECUTE
'TAKE PREVIEW' /* OR 'TAKE RENDER ALL' */
END
END
AT 1 /* before anything else.. */
START init /* start once-off init */
START getscene /* start scene load.. */
START savescene /* ..and save procedures */
START float /* floating all the time */
END
AT 50 /* when all scenes generated.. */
START render
END
AT 5 /* what to do at frame 5 */
START blink /* set it rolling */
END
AT 25 /* what to do at frame 18 */
START blink /* longer blink this time.. */
closingtime = 7 /* ..by overriding default */
END
END /* of program */
The 'housekeeping' is done by the init, getscene, savescene &
render procedures.
The output from this program (Eye.script) can be input to SCULPT
via the 'LOAD SCRIPT' menu option.
I feel it's worth reiterating on the idea of having one, or indeed
a set of, base objects that are modified from scratch for each key-
frame scene.
Imagine that our Eye was installed in a Head and that we wanted the
animation to show a blinking eye, wobbling in a nodding Head.
By having a base object of Head, pointing along one of the SCULPT
axes, containing Eye, also pointing along an axis, we have created
a known starting position of the object(s) for each key-frame scene.
If motions are performed from the bottom of the hierarchy upwards (ie.
Eyelid/Ball, Eye and finally Head) then there is no conflict between
them.
Imagine twisting the Head to one side and then trying to blink the
Eyelid (uummm.. rotate Eyelid about which axis...?).
Such a situation could arise if we base key-frame scene N on key-
frame scene N-1.
Using SCRIPT4D we can code each motion in a separate procedure and
then order the procedures within the program to match the hierarchy
of the objects. The 'nodding, wobbling, blinking eye' would require
a program structure of the form:
FRAMES n
TO blink
...
END
TO wobble
...
END
TO nod
...
END
etc...
Different procedures could, of course, refer to the same part of an
object. For example, you could have one procedure that blinked the
eyelid and another that made it flutter! Either could then be
activated as & when required.
This approach is by no means definitive. After you have studied
the avalable commands you may well decided on a better method.
Again, tell me your ideas!
When it comes to archiving your creations all you need to copy is
the SCRIPT4D program, the TAKE and the Global & base SCENE. There's
no need to keep a copy of all the key-frame scenes because, if they're
needed again, they can be recreated automatically. The saving in disk
space can be huge!
==================================================================
COMMANDS & program structure
==================================================================
The program file is free-form except that all 'tokens' must be
separated by white-space. Case is not significant except within
string variables.
SCRIPT4D is fairly strict when it comes to syntax checking but there
are bound to be a few howlers, so take care - this is version 1 after
all!
A variable, smoother & table can NOT have the same name. However
a procedure can have the same name as any of these without causing
any conflct.
Literals Literals
Three types of literal are recognised by SCRIPT4D:
integers, floating-point & string (enclosed in double
quotes.) For example:
1234
55.7
":SCULPT/SCENES/"
Variables Variables
Most SCRIPT4D commands use named variables to supply or
store values. Variable names are recognised by context
when the program is translated. Names must begin with
an alphabetic character and can be up to 20 characters in
length.
A variable can hold any of the three literal types and is
not restricted to any one type during program execution.
There are two pre-defined variables:
frame holds the current frame number.
This should be considered 'read-only'.
nextframe can be assigned the number of the next
frame to be processed. Useful if you
don't want every frame to be a key-frame.
In the following command descriptions 'variable' parameters are shown
in the form of '<name>'. From the command description it should be
obvious which ones must be variables and which can be literals.
Variables & literals are converted to the type required by the
command when they are accessed. For example, if an integer was
required then variables/literals with these values would all return
an integer value of 34 :
34
34.1
"34fred"
If a specific type of variable/literal MUST be used then the command
description will make that clear.
**************************************************************
The following commands can only appear at the outer level of a
program. They can not appear within procedures or controllers.
FRAMES FRAMES
A FRAMES command should be the first of the program.
It tells SCRIPT4D how many times it should loop through
the program.
Syntax:
FRAMES <number>
Where <number> must be an integer literal.
TABLE TABLE
TABLE commands declare an 'array' of values that can be
accessed at run-time.
Syntax:
TABLE <name> <value>... END
<name> must follow the rules for a variable name.
As many <value>s as required can be specified. Both literals
and variables can be used. In the latter case the value
contained in the variable when the table is accessed will be
used.
Example:
TABLE table1 12 45.7 tiltangle "90" END
See the CHOOSE command for more details.
SMOOTHER SMOOTHER
SMOOTHERs are used to declare a sequence of values that
progress smoothly from one limit to another in a given
number of steps.
Syntax:
SMOOTHER <name> <from> <to> <steps>
<name> follows the rules for a variable name. <from> &
<to> must be integer or floating-point, literals or
variables. <steps> must be an integer literal or variable.
Example:
SMOOTHER twist -20 20 11
Via the SMOOTH command (see later) this would generate values
that vary from -20 to 20 in 11 steps. The value at step 1
would be -20, that at step 6 would be 0 and at step 11 would
be 20. Steps less than zero and beyond the number specified
(11 in this case) can be used - see 'Using Smooth' later.
TO / END TO / END
TO & END are used to name and delimit a procedure.
There are two command blocks within a procedure, SETUP &
EXECUTE, either but not both of which are optional.
Syntax:
TO <name>
SETUP
.
.commands
.
END
EXECUTE
.
.commands
.
END
END
<name> must follow the rules for a variable name.
See the 'START' command.
AT / END AT / END
AT & END delimit a controller block and specifies at which
frame(s) the controller is executed.
Syntax:
AT <frameno>...
.
.commands
.
END
<frameno> must be an integer literal. More than one frame
number can be specified.
Example:
AT 2 7 22 16
START kick
END
*************************************************************
The following commands can only appear within a procedure or
controller.
SCRIPT COMMAND SCRIPT COMMAND
A SCULPT script command is generated by enclosing the
command in single quotes. In fact, any string can be
output by this method.
Syntax:
'...text...' <parameter>...
Parameters enable value substitution within the text string.
Such substitution occurs in the manner of a C language
'printf' function.
For example, the following:
param1 = 45
param2 = 1.23
param3 = "34fred"
'One %d Two %f Three %s' (i) param1 (f) param2 (s) param3
would result in an output of:
One 45 Two 1.23 Three 34fred
The %d, %f & %s formats will be those most commonly used. You
can, however, use any legal conversion specification that may
appear in a C 'printf' format string provided they match the
supplied parameter type.
Note that it's mandatory to force the type of the parameter to
match the required format, whether or not it already has the
appropriate type:
(i) forces to integer
(f) forces to floating-point
(s) forces to string
CHOOSE CHOOSE
Selects a value from a table.
Syntax:
CHOOSE <name> <entry> <result>
<name> must be the name of a previously declared table.
<entry> is a variable or literal that specifies which entry
in the table to retrieve, starting at 1. <result> is the
variable that will take the selected value.
Example:
CHOOSE table1 4 tilt
See 'Assignments' for another way of coding this command.
SMOOTH SMOOTH
Calculates a value from a sequence defined by a SMOOTHER
declaration.
Syntax:
SMOOTH <name> <step> <result>
<name> must be the name of a previously declared smoother.
<step> is a variable or literal that specifies the step for
which a value will be calculated. <result> is the variable
that will take the value.
Example:
SMOOTH twist twiststep twistangle
See 'Using Smooth' for more details.
See 'Assignments' for another way of coding this command.
Assignments Assignments
A direct assignment is of the form:
<dest> = <source>
<dest> must be a variable, <source> can be a variable or
literal of any type.
Arithmetic assignments are of the form:
<dest> += <source>
<dest> -= <source>
<dest> *= <source>
<dest> /= <source>
These perform the appropriate operation on <dest> & <source>
and put the result in <dest>.
For example, the commands:
size = 20
diff = 5
size /= diff
would result in 'size' having a value of 4 ( 20/5 ).
<dest> must be a numeric variable. <source> can be a literal
or variable but must be numeric. Note that <dest> always
retains its type.
Selection assignments are of the form:
<dest> @= <name> <step>
where <name> is a TABLE or SMOOTHER name. <dest> takes the
value of the <step>th entry in the table or smoother. This
is an alternative method of coding SMOOTH & CHOOSE commands.
Example:
tilt @= table1 4
JOIN JOIN
Concatenated strings.
Syntax:
JOIN <this> <onthis>
Both values are, if necessary, converted to strings and
then <this> is appended <tothis>. The result is placed
in <tothis>.
Example:
JOIN "+Lid" object
EXIT EXIT
Used to immediately terminate execution of a procedure for
the current frame.
Syntax:
EXIT
START START
Activates a procedure for subsequent execution.
Syntax:
START <name>
<name> must be a procedure name.
A START command will clear any suspended or frozen state
of the named procedure and execute its SETUP block (if any).
STARTs would normally be used within controllers. If however
a procedure called A (say) STARTs procedure B then B will execute
in the current frame if it appears after A in the program and
will not execute until the next frame if it appears before A
in the program.
DO DO
Executes a procedure immediately.
Syntax:
DO <name>
<name> must be a procedure name.
The EXECUTE block of the named procedure is executed.
No notice is taken of any suspended state nor is it cleared.
A frozen state could be cleared if execution of the procedure
causes its freeze count to decrement to zero.
SUSPEND SUSPEND
Suspends a procedure for a given number of frames.
Syntax:
SUSPEND <name> <suspendcount>
<name> must be a procedure name. <suspendcount> must be a
numeric literal or variable.
Before a procedure is executed a check is made to see if it is
suspended. If so, the suspend count is decremented by 1 and if
it has not reached zero execution of that procedure is skipped.
Example:
SUSPEND eyeroll 16
RESTART RESTART
Activates a suspended procedure &/or thaws a frozen procedure.
Syntax:
RESTART <name>
Example:
RESTART eyeroll
FREEZE FREEZE
FREEZE enables the procedure in which it occurs to be
'frozen' in a particular state for a given number of
frames.
Syntax:
FREEZE <freezecount>
<freezecount> is a numeric variable or literal.
We'll use a modified version of the 'blink' procedure
as an example:
TO blink
...
EXECUTE
blinkangle @= blinking blinkstep
/* ...commands to rotate eyelid by 'blinkangle'... */
IF blinkstep = 7
FREEZE 5
ENDIF
blinkstep += 1
IF blinkstep > 12
SUSPEND blink
ENDIF
END
END
At the 7th step of the blink (ie. when the eye is closed)
the procedure is frozen for 5 frames. Execution of FREEZE
at this point causes the freeze-count to be set to 5 and
the remaining commands of the procedure to be skipped.
Thus blinkstep remains at 7.
In subsequent frames, 'blink' is executed and, again, the
eyelid is rotated to the closed position. The FREEZE
command will execute and provided the freeze-count is zero
then so will the rest of the procedure. Otherwise the
freeze-count is decremented and the remaining commands of
the procedure are skipped.
By this method the rotation of the eyelid remains fixed
because 'blinkstep' is not incremented while the procedure
is frozen.
Note that a RESTART will remove a FREEZE.
IF / ELSE / ENDIF IF / ELSE / ENDIF
These provide for basic conditional processing.
Syntax:
IF <condition>
...commands...
ENDIF
or
IF <condition>
...commands...
ELSE
...commands...
ENDIF
<condition> is a simple comparision of two variables/literals.:
A < B less than
A = B equal to
A > B greater than
A != B not equal to
Example:
IF longdelay = 1
FREEZE 12
ELSE
FREEZE 4
ENDIF
==================================================================
USING SMOOTH
==================================================================
The idea of SMOOTHER & SMOOTH is to aid in the animation of objects
that are to move in an apparently smooth manner from one state to
another by simulating acceleration & deacceleration from & to rest.
Note that this applies to both rotational as well a spatial movement.
The following programs show three ways of using these commands to
get different effects. You'll have to key these progs yourself!
In each case execute the program with a command of the form:
SCRIPT4D <progname
thus defaulting output to the screen for easy viewing.
These programs do not generate SCULPT script commands!
Program 1. Moving from A (at 0) to B (at 500) in 20 steps.
This reqires a SMOOTHER specifying the limits of movement (0 and 500)
and the number of steps (20).
FRAMES 20
SMOOTHER move 0 500 20
TO move
EXECUTE /* remember: 'frame' is pre-defined */
SMOOTH move frame position
'Frame %d, move to %d' (i) frame (i) position
END
END
AT 1
START move
END
END
Program 2. Moving from A to B and back to A in 19 steps
Similar to program 1 with the exception that the move from A to B
has to be done in 10 steps. Thus the SMOOTHER is declared as 10
steps but SMOOTH accesses 19 - 1 TO 10 move from A to B, 11 to 19
move from B to A.
We need an odd number of steps to ensure the middle one (10 in
our case) results in the exact location of B.
FRAMES 19
SMOOTHER move 0 500 10 /* ie. move there in 10 steps */
TO move
EXECUTE
SMOOTH move frame position
'Frame %d, move to %d' (i) frame (i) position
END
END
AT 1
START move
END
END
Program 3. Bounce down from B to A and back again in 19 steps
For the same reason as above this also needs an odd number of steps.
In order to achieve a bounce we must specify a SMOOTHER such that the
bottom of the bounce is half-way between the limits. In addition, at
the half-way point we must increase the current step number by the
total number of steps in order to access the upward motion of the
bounce.
FRAMES 19
SMOOTHER bounce 500 -500 19 /* A is half-way between 500 */
/* and -500 */
TO bounce
SETUP
step = 1
END
EXECUTE
SMOOTH bounce step position
'Frame %d, move to %d' (i) frame (i) position
IF step = 10 /* half way point so.. */
step += 19 /* going up! */
ELSE
step += 1
ENDIF
END
END
AT 1
START bounce
END
END
************************************************************************
END OF DOCUMENTATION FOR VERSION 1.00