; *****************************************************************************
define_command __init_internals
{
; This procedure is called once to initialize all the pre-defined
; global constants and state variables used by skelescript.
; Pre-defined constants:
global_const number pi, 3.14159265358979323846264
global_const number meters_per_foot, 0.3048
global_const number feet_per_meter, (1 / meters_per_foot)
global_const number middle_tolerance, .00000001
global_const string empty_string, ""
global_const int shape_standard, 0
global_const int shape_box, 1
global_const int shape_ball, 2
global_const int shape_pyramid, 3
global_const int shape_diamond, 4
global_const int shape_tetra, 5
global_const int shape_ring, 6
global_const int shape_grid, 7
global_const int shape_none, 8
global_const int axis_x, 0
global_const int axis_y, 1
global_const int axis_z, 2
global_const int justify_left, 0
global_const int justify_center, 1
global_const int justify_right, 2
global_const int color_black, 0
global_const int color_blue, 1
global_const int color_green, 2
global_const int color_teal, 3
global_const int color_red, 4
global_const int color_purple, 5
global_const int color_brown, 6
global_const int color_gray, 7
global_const int color_bright_blue, 8
global_const int color_bright_green, 9
global_const int color_cyan, 10
global_const int color_bright_red, 11
global_const int color_magenta, 12
global_const int color_yellow, 13
global_const int color_white, 14
; Global state variables:
global bool __auto_confirm, false
global bool flip_left_x, false
global bool flip_right_x, false
global bool flip_left_heading, false
global bool flip_left_pitch, false
global bool flip_left_bank, false
global bool flip_right_heading, false
global bool flip_right_pitch, false
global bool flip_right_bank, false
global string left_side_name, "left"
global string middle_side_name, "middle"
global string right_side_name, "right"
}
; *****************************************************************************
; For declaring variables and constants:
define_command local(int data_type, identifier name, any value) {__local 0, data_type, name, value, 1}
define_command const(int data_type, identifier name, any value) {__local 1, data_type, name, value, 1}
define_command global(int data_type, identifier name, any value) {__global 0, data_type, name, value}
define_command global_const(int data_type, identifier name, any value) {__global 1, data_type, name, value}
; *****************************************************************************
; For declaring local variables:
define_command any(identifier name, any value=0) {__local false, any, name, value, 1 }
define_command string(identifier name, string value="") {__local false, string, name, value, 1 }
define_command number(identifier name, number value=0.0) {__local false, number, name, value, 1 }
define_command int(identifier name, int value=0) {__local false, int, name, value, 1 }
define_command bool(identifier name, bool value=false) {__local false, bool, name, value, 1 }
define_command item_id(identifier name, item_id value=selected) {__local false, item_id, name, value, 1 }
define_command collection(identifier name, collection value=create_collection) {__local false, collection, name, value, 1 }
define_command identifier(identifier name, identifier value) {__local false, identifier, name, value, 1 }
; For declaring local constants:
define_command const_any(identifier name, any value=0) {__local true, any, name, value, 1 }
define_command const_string(identifier name, string value="") {__local true, string, name, value, 1 }
define_command const_number(identifier name, number value=0.0) {__local true, number, name, value, 1 }
define_command const_int(identifier name, int value=0) {__local true, int, name, value, 1 }
define_command const_bool(identifier name, bool value=false) {__local true, bool, name, value, 1 }
define_command const_item_id(identifier name, item_id value=selected) {__local true, item_id, name, value, 1 }
define_command const_collection(identifier name, collection value=create_collection) {__local true, collection, name, value, 1 }
define_command const_identifier(identifier name, identifier value) {__local true, identifier, name, value, 1 }
; For declaring global variables:
define_command global_any(identifier name, any value=0) {__global false, any, name, value}
define_command global_string(identifier name, string value="") {__global false, string, name, value}
define_command global_number(identifier name, number value=0.0) {__global false, number, name, value}
define_command global_int(identifier name, int value=0) {__global false, int, name, value}
define_command global_bool(identifier name, bool value=false) {__global false, bool, name, value}
define_command global_item_id(identifier name, item_id value=selected) {__global false, item_id, name, value}
define_command global_collection(identifier name, collection value=create_collection) {__global false, collection, name, value}
define_command global_identifier(identifier name, identifier value) {__global false, identifier, name, value}
; For declaring global constants:
define_command global_const_any(identifier name, any value=0) {__global true, any, name, value}
define_command global_const_string(identifier name, string value="") {__global true, string, name, value}
define_command global_const_number(identifier name, number value=0.0) {__global true, number, name, value}
define_command global_const_int(identifier name, int value=0) {__global true, int, name, value}
define_command global_const_bool(identifier name, bool value=false) {__global true, bool, name, value}
define_command global_const_item_id(identifier name, item_id value=selected) {__global true, item_id, name, value}
define_command global_const_collection(identifier name, collection value=create_collection) {__global true, collection, name, value}
define_command global_const_identifier(identifier name, identifier value) {__global true, identifier, name, value}
; *****************************************************************************
define_function collection __server_collection(item_id item, string plugin_class)
{
; Returns a collection of the plugins applied to the item under the specific
; class. Example of a plugin_class would be "CustomObjHandler" and
; "ItemMotionHandler". Examine scene files to learn different plugin classes
; and the formats of each plugin.
Collection c, create_collection(string)
int j, 1
string plugin_name
while (set(plugin_name, __server(item, plugin_class, post_inc(j)) ) != "") {push c, plugin_name}
return c
}
; *****************************************************************************
define_command add_item_shape(
item_id item = selected,
int shape = shape_ball,
number scale = 0.2,
bool filled = false,
number opacity = 1.0,
int axis = axis_y,
collection selected_color = empty_collection,
collection unselected_color = empty_collection,
collection text_color = empty_collection,
string label = empty_string,
int justify = justify_center,
item_id draw_to_item = null_item)
{
; scale specifies the size of the shape in meters.
collection plugins, __server_collection(item, "CustomObjHandler")
if (find_element(plugins, "LW_ItemShape") != -1) {error "Cannot add Item Shape plugin to object. An Item Shape plugin already exists."}
int flags, 0
if (justify == justify_left) {set flags, bitwise_or(flags, 8) }
else_if (justify == justify_right)
{
set flags, bitwise_or(flags, 8)
set flags, bitwise_or(flags, 16)
}
if (collection_empty(selected_color) ) {set selected_color, rgb(0, 0, 0) }
else {set flags, bitwise_or(flags, 1) }
if (collection_empty(unselected_color) ) {set unselected_color, rgb(0, 0, 0) }
else {set flags, bitwise_or(flags, 2) }
if (collection_empty(text_color) ) {set text_color, rgb(0, 0, 0) }
else {set flags, bitwise_or(flags, 4) }
string str
if (label != empty_string) {concat_line str, ("// LABEL=" & label) }
concat_line str, ("Plugin CustomObjHandler " & (collection_size(plugins) + 1) & " LW_ItemShape")
concat_line str, 4
concat_line str, concat_lines(scale, axis, shape, filled, flags)
concat_line str, collection_text(rgb_to_float(selected_color), " ")
concat_line str, collection_text(rgb_to_float(unselected_color), " ")
concat_line str, collection_text(rgb_to_float(text_color), " ")
concat_line str, opacity
concat_line str, __raw_id(draw_to_item)
concat_line str, ("\"" & label & "\"")
concat_line str, ("EndPlugin")
__scene_modification item, str
}
; *****************************************************************************
define_command add_gravity(item_id item = selected, int start_frame = 1, int end_frame = 60, number ground_level = 0.0, number strength = 1.0, number elasticity = 0.25, integer axis = axis_y)
{
collection plugins, __server_collection(item, "ItemMotionHandler")
if (find_element(plugins, "LW_Gravity") != -1) {error "Cannot add LW_Gravity plugin to object. An LW_Gravity plugin already exists."}
string str, ("Plugin ItemMotionHandler " & (collection_size(plugins) + 1) & " LW_Gravity")
concat_line str, ("Axis " & axis & " Strength " & strength)
concat_line str, ("Start " & start_frame & " End " & end_frame)
concat_line str, ("Ground " & ground_level & " Elasticity " & sqrt(elasticity) )
concat_line str, ("EndPlugin")
__scene_modification item, str
}
; *****************************************************************************
define_command add_simple_follower(item_id item = selected,
bool after_ik = false, bool heading_active = true, bool pitch_active = true, bool bank_active = true,
item_id item1 = null_item, number heading1 = 0.0, number pitch1 = 0.0, number bank1 = 0.0,
item_id item2 = null_item, number heading2 = 0.0, number pitch2 = 0.0, number bank2 = 0.0)
{
collection plugins, __server_collection(item, "ItemMotionHandler")
if (find_element(plugins, "SimpleFollower") != -1) {error "Cannot add SimpleFollower plugin to object. A SimpleFollower plugin already exists."}
string str, ("Plugin ItemMotionHandler " & (collection_size(plugins) + 1) & " SimpleFollower")
concat_line str, 1
concat_line str, __raw_id(item1)
concat_line str, __raw_id(item2)
concat_line str, after_ik
concat_line str, concat_lines(heading_active, heading1, heading2)
concat_line str, concat_lines(pitch_active, pitch1, pitch2)
concat_line str, concat_lines(bank_active, bank1, bank2)
concat_line str, ("EndPlugin")
__scene_modification item, str
}
; *****************************************************************************
; Procedures for working with angle type values. Valid angle_type constants
; are: angle_heading, angle_pitch, and angle_bank.
define_function string angle_type_name(int angle_type)
{
; Returns a string for the name of the specified angle type.
if (angle_type == angle_heading) {return "heading"}
if (angle_type == angle_pitch) {return "pitch"}
if (angle_type == angle_bank) {return "bank"}
__error_invalid_angle_type angle_type
}
define_command assert_valid_angle_type(int angle_type)
{
if (angle_type == angle_heading || angle_type == angle_pitch || angle_type == angle_bank) {return}
__error_invalid_angle_type(angle_type)
}
define_command __error_invalid_angle_type(int angle_type)
{
; Displays an error message telling the user that the specified angle type is invalid.
error ("Invalid angle type: " & angle_type & ". Valid values are: angle_heading, angle_pitch, and angle_bank.")
}
; *****************************************************************************
define_function bool is_only_item_selected(item_id item)
{
; Returns true if the item is selected and no other items
; are selected.
return (num_selected == 1 && item == selected)
}
; *****************************************************************************
define_function collection rgb(int red, int green, int blue)
{
if (red < 0 || red > 255) {error "Invalid color. The red component must be in the range of 0 to 255."}
if (green < 0 || green > 255) {error "Invalid color. The green component must be in the range of 0 to 255."}
if (blue < 0 || blue > 255) {error "Invalid color. The blue component must be in the range of 0 to 255."}
return create_collection(int, red, green, blue)
}
define_function collection rgb_to_float(collection c)
{
; Converts an integer-based RGB color collection with values ranging from 0
; to 255 to a floating value-based RGB color collection with values ranging
; from 0 to 1.0.
return create_collection(number, c(0) / 255.0, c(1) / 255.0, c(2) / 255.0)
}
; *****************************************************************************
define_function string concat(any lhs, ~any remaining)
{
; Concatenates the specified values to form a single,
; combined string which is returned by the function.
string str, tostring(lhs)
for_each remaining, arg {concat str, arg}
return str
}
; *****************************************************************************
define_function string concat_lines(any lhs, ~any remaining)
{
; Concatenates the specified lines to form a single,
; multi-line string which is returned by the function.
string str, tostring(lhs)
for_each remaining, arg {concat str, ("\n" & tostring(arg)) }
return str
}
; *****************************************************************************
define_function string command_line(string command, ~any remaining)
{
; Returns a command line formed from the specified command
; and the arguments with the arguments separated by spaces.
string str, command
for_each remaining, arg
{
concat str, " "
concat str, arg
}
return str
}
; *****************************************************************************
; Unit Conversion Functions
define_function number radians_to_degrees(number radians) {return mul(radians / pi, 180.0) }
define_function number degrees_to_radians(number degrees) {return mul(degrees / 180.0, pi) }
define_function number feet_to_meters(number feet) {return mul(feet, meters_per_foot) }
define_function number meters_to_feet(number meters) {return mul(meters, feet_per_meter) }
; *****************************************************************************
; The following allows the user to set the auto-confirm status. Skelescripts
; keeps track of the auto-confirm status.
define_command AutoConfirm(bool value)
{
; Overrides the native AutoConfirm command with the additional
; function of keeping track of the auto-confirm status.
__native_command ("AutoConfirm " & set(__auto_confirm, value) )
}
define_get bool auto_confirm {return __auto_confirm }
define_set bool auto_confirm {AutoConfirm value}
; *****************************************************************************
define_function string side(item_id item = selected, string left_str = left_side_name, string middle_str = middle_side_name, string right_str = right_side_name)
{
if (world_x(item) < -middle_tolerance) {return left_str}
if (world_x(item) > middle_tolerance) {return right_str}
return middle_str
}
; *****************************************************************************
define_command move_to_ground (item_id item = selected)
{
; Moves the specified item so that it's y position is 0.
if (local_y == world_y) {execute_for_item item, "Position world_x, 0, world_z"}
else {execute_for_item item, "AddPosition 0, (-world_y), 0"}
}
; *****************************************************************************
define_command delete(item_id item = selected)
{
; Deletes the specified item without confirmation.
bool prev_auto_confirm auto_confirm
set auto_confirm, true
execute_for_item item, "ClearSelected"
set auto_confirm, prev_auto_confirm
}
; *****************************************************************************
define_command lock_all_channels(item_id item = selected)
{
; Locks all the channels available with the current layout tool for the
; specified item.
execute_for_item item, "enableXH\nenableYP\nenableZB"
}
; *****************************************************************************
define_command lock_movement(item_id item = selected)
{
; locks all the movement channels for the specified item.
movetool
lock_all_channels item
}
; *****************************************************************************
define_command lock_rotation(item_id item = selected)
{
; locks all the rotational channels for the specified item.
rotatetool
lock_all_channels item
}
; *****************************************************************************
; Returns the current frame based on the current time and the
; number of frames per second. Fractional frames are not currently
; supported.
define_get int current_frame {return round(current_time * fps) }
; Sets the current frame.
define_set int current_frame {(GoToFrame value}
; Returns the current fps.
define_set int fps {FramesPerSecond value}
; *****************************************************************************
define_function collection empty_collection
{
; Returns an empty collection.
return create_collection(any)
}
; *****************************************************************************
define_function string collection_text(collection c, string separator = ", ", string empty_text = "empty", string inner_prefix = "(", string inner_suffix = ") ")
{
; converts a collection to a string which specifies its elements. Unlike
; tostring, this function gives you control over how to output the collection.
if (collection_empty(c)) {return empty_text}
int num_elements, collection_size(c)
int j, 0
string str, __collection_text_impl(j, c, separator, empty_text, inner_prefix, inner_suffix)
while (inc(j) < num_elements) {concat str, (separator & __collection_text_impl(j, c, separator, empty_text, inner_prefix, inner_suffix)) }
return str
}
define_function string __collection_text_impl(int j, collection c, string separator = ", ", string empty_text = "empty", string inner_prefix = "(", string inner_suffix = ")")
{
any element, c(j)
if (is_collection(element) ) {return (inner_prefix & collection_text(element, separator, empty_text, inner_prefix, inner_suffix) & inner_suffix) }
return tostring(element)
}
; *****************************************************************************
define_command push(collection c, any element)
{
; Pushes an element to the back of the collection.
assert collection_insert(c, element)
}
define_function any pop(collection c)
{
; Removes and returns the element at the back of the collection.
if (collection_empty(c)) {error "Cannot pop elements from an empty collection."}
int last_index, (collection_size(c) - 1)
any element, c(last_index)
assert collection_erase(c, last_index)
return element
}
define_command pop(collection c) {run pop(c) }
; *****************************************************************************
define_function int find_element(any c, any search_element)
{
; Searches the specified collection/string for the specified element/character.
; The function returns an index (greater than or equal to 0) if the element is
; found. Otherwise, the function returns -1.
int num_elements, size(c)
int j, -1
while (inc(j) < num_elements)
{
if (element(c, j) == search_element) {return j}
}
return -1
}
; *****************************************************************************
define_function int size(any c)
{
if (is_collection(c)) {return collection_size(c)}
if (is_string(c)) {return length(c)}
error "The argument passed to the size function must be a string or a collection."
}
; *****************************************************************************
define_get any element(any elements, any pos)
{
; Returns the specified element in a collection or a string. For strings,
; a single character is returned.
if (is_collection(elements) ) {return elements(pos) }
else_if (is_string(elements) ) {return char_at(elements, pos) }
else {error "Invalid data type specified for element property. Expected a string or a collection."}
}
; *****************************************************************************
define_set any element(any& elements, any position)
{
; Sets the value of the specified element in a collection or a string.
if (is_collection(elements) ) {set elements(position), value}
else_if (is_string(elements) ) {set char_at(elements, position), value }
else {error "Invalid data type specified for element property. Expected a string or a collection."}
}
; *****************************************************************************
define_get string char_at(string str, int pos)
{
; Returns the character at the specified position.
; The set procedure of char_at is defined internally.
return substr(str, pos, 1)
}
; *****************************************************************************
define_command swap(any& value1, any& value2)
{
; Swaps the values of two variables. The variables must be of
; compatible data types.
local any, temp, value1
set value1, value2
set value2, temp
}
; *****************************************************************************
; Increments the specified variable by the specified amount. The function
; also returns the resulting value.
define_command inc(number& source, number amount = 1) {run inc(source, amount) }
define_function number inc(number& source, number amount = 1) {return set(source, source + amount)}
; Decrements the specified variable by the specified amount. The function
; also returns the resulting value.
define_command dec(number& source, number amount = 1) {run dec(source, amount) }
define_function number dec(number& source, number amount = 1) {return set(source, source - amount)}
define_function number post_inc(number& source, number amount = 1)
{
; Increments the specified variable by the specified amount and
; returns the original value before incrementing.
int temp, source
run inc(source, amount)
return temp
}
define_function number post_dec(number& source, number amount = 1)
{
; Decrements the specified variable by the specified amount and
; returns the original value before decrementing.
int temp, source
run dec(source, amount)
return temp
}
; *****************************************************************************
; Arithmetical Functions:
define_function number add(number lhs, ~number remaining)
{
; Returns the sum of two or more numbers.
for_each remaining, element {inc lhs, element}
return lhs
}
define_function number sub(number lhs, ~number remaining)
{
; Returns the difference of two or more numbers
; (calculated from left to right).
for_each remaining, element {dec lhs, element}
return lhs
}
define_function number mul(number lhs, ~number remaining)
{
; Returns the product of two or more numbers.
for_each remaining, element {mul lhs, element}
return lhs
}
define_command mul(number& lhs, number rhs) {set lhs, (lhs * rhs) }
define_function number div(number lhs, ~number remaining)
{
; Returns the quotient of after dividing two or more numbers.
for_each remaining, element {div lhs, element}
return lhs
}
define_command div(number& lhs, number rhs) {set lhs, (lhs / rhs) }
; *****************************************************************************
; These functions return the absolute position relative to an item with
; a given offset. Ex - the relative_x function with an item with the X position
; of 30 will return 20 if the offset is -10. Moreover, the functions accomodate for
; position flipping, so if flip_right_x is on, the function will return 40 instead of
; 20 since it'll flip the -10 offset into 10 since an X position of 30 means that the
; item is on the right side.
define_function number relative_x(item_id item, number add_x)
{
number item_x, world_x(item)
; Flip the offset if the item is on the left side flip_left_x is on or if
; it's on the right side flip_right_x is on.
if ( (item_x < 0 && flip_left_x) || (item_x > 0 && flip_right_x) ) {set add_x, (add_x * -1.0) }
return (add_x + item_x)
}
define_function number relative_y(item_id item, number add_y) {return (add_y + world_y(item)) }
define_function number relative_z(item_id item, number add_z) {return (add_z + world_z(item)) }
; *****************************************************************************
; Functions to create nulls for various purposes.
define_function item_id create_null(string name, number x = 0, number y = 0, number z = 0)
{
; Creates a null at the specified position and returns the ID.
store_selection
AddNull name
item_id null_id, selected
Position x, y, z
restore_selection
return null_id
}
define_function item_id create_null_at(item_id item, string name, number add_x = 0, number add_y = 0, number add_z = 0)
{
; Creates a null at a position relative to the specified item's position and
; returns the ID. If orient_null is true, the newly created null will be oriented
; to match the item's orientation.
return create_null(name, relative_x(item, add_x), relative_y(item, add_y), relative_z(item, add_z) )
}
define_function item_id create_oriented_null_at(item_id item, string name, number add_x = 0, number add_y = 0, number add_z = 0)
{
; Creates and returns the ID of a null that is oriented to match the selected
; item's orientation. The null is created at a position that is relative to the
; specified item's position.
store_selection
bool prev_parent_in_place, parent_in_place
AddNull name
set parent_in_place, false
set parent, item
set parent_in_place, true
set parent, null_item
AddPosition add_x, add_y, add_z
item_id null_id, selected
restore_selection
set parent_in_place, prev_parent_in_place
return null_id
}
define_command create_goal(bool full_time = true, string null_name = concat(name, "_goal"), number add_x = 0, number add_y = 0, number add_z = 0)
{
; Creates a goal null for the selected item at the specified relative