Offsets

From Data Realms Wiki

(Difference between revisions)
Jump to: navigation, search
m (Linked to more informative video lesson on vectors)
(Factually corrected)
Line 1: Line 1:
-
Offsets define relative positions of many things in Cortex Command. They describe individual points mapping to individual pixels within [http://en.wikipedia.org/wiki/Sprite_%28computer_graphics%29 sprites]. Those points are used to position a sprite in relation to another sprite, and Offsets relative to other Offsets. They define where things are, like the [[HDFirearm | gun]] carried by a [[AHuman | soldier]], and also where things are emitted from, like the bullets from that gun.
+
Offsets define relative positions of many things in Cortex Command. They describe individual points which the game engine maps to individual pixels within [http://en.wikipedia.org/wiki/Sprite_%28computer_graphics%29 sprites] as they move and rotate on screen. Those points are used to position a sprite in relation to another sprite, such as the shoulder joint on an arm sprite and the corresponding shoulder on its "parent" torso sprite. They define where things are, like the [[HDFirearm | gun]] carried by a [[AHuman | soldier]], and also where things are emitted from, like the bullets from that gun.
-
You'll need to understand [http://en.wikipedia.org/wiki/Cartesian_coordinate_system Cartesian coordinates] and arithmetic with positive and negative numbers.
+
You'll need to understand [http://en.wikipedia.org/wiki/Cartesian_coordinate_system Cartesian coordinates] and arithmetic with positive and negative numbers. Offset values are usually [http://en.wikipedia.org/wiki/Integer integers] but Offsets accept [http://en.wikipedia.org/wiki/Floating_point float values] (most often just "_.5"). Though you'll never see half a pixel, Cortex Command's math does. Inaccurate values create inaccuracies in drawing pixels.
 +
 
 +
And if you understand [http://www.khanacademy.org/math/linear-algebra/v/linear-algebra--vector-examples vectors], you'll understand positioning Offsets relative to other Offsets, almost always done relative to the SpriteOffset. <br>
== SpriteOffset ==
== SpriteOffset ==
-
If sprites in Cortex Command were paper drawings, cut out and pinned to a background, the SpriteOffset would be where the push pin goes though the cutout. If you spin the cutout, it spins around the pin. In physics, things spin around their own [http://en.wikipedia.org/wiki/Center_of_mass center of mass]. The SpriteOffset provides something similar.
+
If sprites in Cortex Command were paper drawings, cut out and pinned to a cork board, the SpriteOffset would be where the push pin goes though the cutout. If you spin the cutout, it spins around the pin. In physics, things spin around their own [http://en.wikipedia.org/wiki/Center_of_mass center of mass]. The SpriteOffset provides something similar.
-
Cortex Command uses pixels, not paper, and pixels have coordinates. Any coordinate system needs an origin-- “X = 0, Y = . The origin works like the push pin for positioning and moving sprites. If you open a sprite's image file in an image editor, all the pixels are positive [http://en.wikipedia.org/wiki/Integer integers] except the pixel up in the top left which is (0,0). But this pixel shouldn't represent the center of mass. The pixel which should-- for this and some other reasons-- is the very center one. <br>
+
=== Coordinates & Pixels ===
-
'''The SpriteOffset is the center pixel's equal, opposite X and Y values that make its coordinates (0,0) when added together'''. All pixels in the image editor have positive values, so the SpriteOffset ought to be negative. And every pixel in the sprite is offset by this same amount. It's like holding the push pin still and moving the drawing under it, left and up, before sticking the correct spot.  
+
Cortex Command uses pixels, not paper, and pixels have [http://en.wikipedia.org/wiki/Integer integer] coordinates. A coordinate system needs an origin: ''“X = 0, Y = 0''”. Cortex Command uses the SpriteOffset as the origin for each sprite, and all other Offsets are distances, or [http://www.khanacademy.org/math/linear-algebra/v/linear-algebra--vector-examples vectors], measured from the SpriteOffset measured in pixel lengths on the X and Y axes. <br>
 +
If you open a sprite's image file in an image editor (MS Paint, GIMP, Photoshop, etc.), the coordinates of every pixel is a positive integer value, and it's the pixel up in the top left which has the coordinate ''(0,0)''. But this pixel probably shouldn't represent the center of mass. <br>
 +
Instead of a push pin positioned over paper, think of positioning over the pixels of the image an invisible, purely mathematical pixel which, by default, is squarely over that top left pixel in the image. This is the SpriteOffset and it can be offset any distance along the X and Y axes, on or off the image, whole or decimal lengths from its natural starting place over (0,0).  
-
Offsets map to single pixels, but they're measured in [http://www.khanacademy.org/math/linear-algebra/v/linear-algebra--vector-examples vectors] for the math deciding where each pixel is drawn. They accept [http://en.wikipedia.org/wiki/Floating_point float values]. Though you'll never see half a pixel, the math does. Inaccurate values create inaccuracies in drawing pixels. <br>
+
==== Which Axis Is Flipped? ====
 +
There are two ways of looking at how to find coordinates to position Offsets. <br>
 +
More mathematically true is the perspective of moving the pin/pixel over the paper/image from the natural origin in the top left. In Cortex Command, one axis has its positive and negative reversed from the Cartesian model; and in this "pin" perspective the X-axis is flipped so right is negative and left is positive. It also means measuring vectors of "child" Offsets back to the SpriteOffset of the parent sprite. <br>
 +
The other perspective is more true to how things look in game since Cortex Command moves sprites via their SpriteOffset and visually appear to extending down and to the right from it with ''X = 0'' and ''Y = 0''. This perspective holds the pin/pixel still while moving the paper/image underneath it, typically to the left and up. In this perspective the Y-axis is flipped so up is negative and down is positive. It also means you measure vectors out from the SpriteOffset out to any "child" Offsets. <br>
 +
Which perspective you use is irrelevant as the numbers you enter will be the same. '''Just be consistent.'''
-
=== Offset Coordinates ===
+
=== Centering the Odds of Evening ===
 +
Typically the SpriteOffset will define a pixel in the very center of the sprite, though official examples such as the [[Dummy#Dummy | Dummy infantry]] position it centered only on the X-axis and low to the hip on the Y-axis. Since sprites are horizontally mirrored, or "HFlipped", to face left, visual popping may occur if the X value of the SpriteOffset is off-center on the X-axis. The Y-axis is more forgiving.
-
Since the SpriteOffset sets the origin, coordinates for any other Offsets are relative to it.  
+
Positioning the SpriteOffset can be tricky because image sizes are reported as a count of the total number of pixels. A 5x5 image has pixels ranging from (0,0) only up to (4,4). Typically it's easier to find the image size than the coordinate of the bottom right pixel. The middle can be found by subtracting 1 from width or height and dividing by 2. Offsets accept decimal, or [http://en.wikipedia.org/wiki/Floating_point float], values. <br>
 +
Even numbered WxH size, to have an equal number of pixels to either side (left & right, above & below) the SpriteOffset, would have ''_.5'' values; or you can just divide width and height in half and it's good enough. Odd numbered widths more consistently map to a specific pixel even as the sprite spins around. <br>
-
Here is where it briefly gets tricky... <br>
+
To put the center of mass where, visually, it ought to be ''and'' avoid visual popping, it may be wisest to enlarge the canvas as needed to keep an equal number of pixels horizontally (and perhaps vertically) on either side of the center of mass pixel when setting it as the SpriteOffset.
-
Cortex Command's coordinates differ from Cartesian in one important way: the Y (or vertical) axis is inverted-- up is negative-Y. Left is still negative-X, and right positive. This has been tested and checked in-game for all the Offsets described here.  
+
-
To assign any other Offset to a pixel of the sprite, count how many pixels away it is from the SpriteOffset origin pixel horizontally and vertically, paying attention to which directions are positive and negative.
 
== Offset ==
== Offset ==
Line 38: Line 46:
== ParentOffset ==
== ParentOffset ==
-
Used to adjust the positioning of things logically attached as a "child" to a sprite. These things are typically sprites themselves or an emitter. Magazines attached to HDFirearms use ParentOffset to position themselves correctly. However, it accepts values beyond the pixel area of the sprite attached to.
+
Used when attaching a "child" sprite, the ParentOffset defines a point relative to the "parent" sprite's SpriteOffset which the child's JointOffset will attach to. For example, it defines a shoulder socket which the arm's shoulder forms a joint with. [[HDFirearm | HDFirearms]] use ParentOffset to define a receiver which the Magazine's JointOffset will snap into. The child is typically a sprite or an [[AEmitter]].
== JointOffset ==
== JointOffset ==
-
Used in connecting animated objects together. It specifies a pixel as a joining point which will be used automatically by anything Cortex Command is setup to join with it. Parts of an [[Actors | Actor's]] body are joined to each other with via JointOffset, as are various [[Devices]] like guns and tools. This applies to Actor types like [[ADoor]], [[ACRocket]], and [[ACDropShip]]. Attachable effects and [[AEmitter]] also use this.
+
Used when attaching as a "child" to a "parent" sprite, the JointOffset defines a point relative to the child sprite's SpriteOffset which the parent can grab onto and position on itself using it's ParentOffset. Parts of an [[Actors | Actor's]] body are joined to each other with via JointOffset, as are various [[Devices]] like guns and tools. This applies to Actor types like [[ADoor]], [[ACRocket]], and [[ACDropShip]]. Attachable effects and [[AEmitter]] also use this.
For [[HDFirearm]]s, the JointOffset is where the FGArm (foreground arm) Hand is positioned, typically where the trigger is drawn but it has no effect on firing the [[Weapons | weapon]] or [[Tools | tool]]. If placed too far for an AHuman's Hand to reach, the arm will twitch, trying and failing to reach the JointOffset.
For [[HDFirearm]]s, the JointOffset is where the FGArm (foreground arm) Hand is positioned, typically where the trigger is drawn but it has no effect on firing the [[Weapons | weapon]] or [[Tools | tool]]. If placed too far for an AHuman's Hand to reach, the arm will twitch, trying and failing to reach the JointOffset.

Revision as of 00:10, 25 January 2013

Offsets define relative positions of many things in Cortex Command. They describe individual points which the game engine maps to individual pixels within sprites as they move and rotate on screen. Those points are used to position a sprite in relation to another sprite, such as the shoulder joint on an arm sprite and the corresponding shoulder on its "parent" torso sprite. They define where things are, like the gun carried by a soldier, and also where things are emitted from, like the bullets from that gun.

You'll need to understand Cartesian coordinates and arithmetic with positive and negative numbers. Offset values are usually integers but Offsets accept float values (most often just "_.5"). Though you'll never see half a pixel, Cortex Command's math does. Inaccurate values create inaccuracies in drawing pixels.

And if you understand vectors, you'll understand positioning Offsets relative to other Offsets, almost always done relative to the SpriteOffset.

Contents

SpriteOffset

If sprites in Cortex Command were paper drawings, cut out and pinned to a cork board, the SpriteOffset would be where the push pin goes though the cutout. If you spin the cutout, it spins around the pin. In physics, things spin around their own center of mass. The SpriteOffset provides something similar.

Coordinates & Pixels

Cortex Command uses pixels, not paper, and pixels have integer coordinates. A coordinate system needs an origin: “X = 0, Y = 0”. Cortex Command uses the SpriteOffset as the origin for each sprite, and all other Offsets are distances, or vectors, measured from the SpriteOffset measured in pixel lengths on the X and Y axes.
If you open a sprite's image file in an image editor (MS Paint, GIMP, Photoshop, etc.), the coordinates of every pixel is a positive integer value, and it's the pixel up in the top left which has the coordinate (0,0). But this pixel probably shouldn't represent the center of mass.
Instead of a push pin positioned over paper, think of positioning over the pixels of the image an invisible, purely mathematical pixel which, by default, is squarely over that top left pixel in the image. This is the SpriteOffset and it can be offset any distance along the X and Y axes, on or off the image, whole or decimal lengths from its natural starting place over (0,0).

Which Axis Is Flipped?

There are two ways of looking at how to find coordinates to position Offsets.
More mathematically true is the perspective of moving the pin/pixel over the paper/image from the natural origin in the top left. In Cortex Command, one axis has its positive and negative reversed from the Cartesian model; and in this "pin" perspective the X-axis is flipped so right is negative and left is positive. It also means measuring vectors of "child" Offsets back to the SpriteOffset of the parent sprite.
The other perspective is more true to how things look in game since Cortex Command moves sprites via their SpriteOffset and visually appear to extending down and to the right from it with X = 0 and Y = 0. This perspective holds the pin/pixel still while moving the paper/image underneath it, typically to the left and up. In this perspective the Y-axis is flipped so up is negative and down is positive. It also means you measure vectors out from the SpriteOffset out to any "child" Offsets.
Which perspective you use is irrelevant as the numbers you enter will be the same. Just be consistent.

Centering the Odds of Evening

Typically the SpriteOffset will define a pixel in the very center of the sprite, though official examples such as the Dummy infantry position it centered only on the X-axis and low to the hip on the Y-axis. Since sprites are horizontally mirrored, or "HFlipped", to face left, visual popping may occur if the X value of the SpriteOffset is off-center on the X-axis. The Y-axis is more forgiving.

Positioning the SpriteOffset can be tricky because image sizes are reported as a count of the total number of pixels. A 5x5 image has pixels ranging from (0,0) only up to (4,4). Typically it's easier to find the image size than the coordinate of the bottom right pixel. The middle can be found by subtracting 1 from width or height and dividing by 2. Offsets accept decimal, or float, values.
Even numbered WxH size, to have an equal number of pixels to either side (left & right, above & below) the SpriteOffset, would have _.5 values; or you can just divide width and height in half and it's good enough. Odd numbered widths more consistently map to a specific pixel even as the sprite spins around.

To put the center of mass where, visually, it ought to be and avoid visual popping, it may be wisest to enlarge the canvas as needed to keep an equal number of pixels horizontally (and perhaps vertically) on either side of the center of mass pixel when setting it as the SpriteOffset.


Offset

Used by Exit hatches on ACRockets and Terrain material bitmaps. Also used by the Gib entity; this is best left to the Gib Editor included in Cortex Command.


Bitmap Offset

Used for static elements on a map, including TerrainObject set pieces, Bunker Backgrounds and Bunker Bits, as well as the old Brain Vault, Rocket Silo, and Wall. Almost all of their vectors are 0,0 but certain Geology objects and the three old Bunker modules use negative vectors.


EmissionOffset

Used by AEmitter entities to define which pixel the things it emits are emitted from, in many ways similar to MuzzleOffset.


ParentOffset

Used when attaching a "child" sprite, the ParentOffset defines a point relative to the "parent" sprite's SpriteOffset which the child's JointOffset will attach to. For example, it defines a shoulder socket which the arm's shoulder forms a joint with. HDFirearms use ParentOffset to define a receiver which the Magazine's JointOffset will snap into. The child is typically a sprite or an AEmitter.


JointOffset

Used when attaching as a "child" to a "parent" sprite, the JointOffset defines a point relative to the child sprite's SpriteOffset which the parent can grab onto and position on itself using it's ParentOffset. Parts of an Actor's body are joined to each other with via JointOffset, as are various Devices like guns and tools. This applies to Actor types like ADoor, ACRocket, and ACDropShip. Attachable effects and AEmitter also use this.

For HDFirearms, the JointOffset is where the FGArm (foreground arm) Hand is positioned, typically where the trigger is drawn but it has no effect on firing the weapon or tool. If placed too far for an AHuman's Hand to reach, the arm will twitch, trying and failing to reach the JointOffset.


Device-Specific Offsets

These Offsets are used only by the various types of Devices: HeldDevices, HDFirearms, or TDExplosives.

SupportOffset

This defines where the BGArm (background arm) Hand of AHuman is positioned on a Device. Even one-handed devices specify a SupportOffset, though it tends to be close to the JointOffset. Excessive values have the same effect on the BGArm as excessive JointOffsets have on the FGArm.

StanceOffset

Adjustment where the SpriteOffset of a HeldDevice, HDFirearm, or ThrownDevice lines up with the SpriteOffset of the Actors carrying it. If a Device is meant to be carried high, slung low, held forward, or tucked back, this is where it should be specified, not SpriteOffset. Note that changing the StanceOffset does not change other Offsets-- they remain relative to SpriteOffset only. However, excessive values on StanceOffset can put other Offsets beyond reach of an AHuman's Hands.

SharpStanceOffset

Adjustments where a HeldDevice or HDFirearm and an Actor's SpriteOffsets align, but only when stopping to aim. Most weapons (and even the diggers, for some reason) are carried higher to "look down the sights" though it can be set arbitrarily. Like SupportOffset, all other Offsets on the Device stay relative to the SpriteOffset, thus the "move with" the Device.

MuzzleOffset

Defines the pixel where any Round an HDFirearm fires are emitted from. Typically this is the forward tip of the barrel, but it can be placed arbitrarily, even outside the sprite's pixel area.

EjectionOffset

The pixel where any Shell will be emitted from the sprite of an HDFirearm.


StartThrowOffset

Used with TDExplosives such as grenades. Almost always (-12,-5).

EndThrowOffset

Used with TDExplosives such as grenades. Almost always (-12,-5) but sometise (12,-5).


Actor-Specific Offsets

These Offsets are used only by the various types of Actors: AHumans, ACrabs, ACRockets, ACDropShips, or ADoors.

IdleOffset

Used to position the Hand on an Arm when its Actor isn't equipped with any Device, and for the Foot on a Leg when standing.

ExtendedOffset

Defines where the Foot of an Actor is positioned relative to the Actor's SpriteOffset when standing. Note that these coordinates assume the Leg being oriented horizontally as sprites for them are.

ContractedOffset

Used when crouching, this defines where the Foot of an Actor is positioned relative to the Actor's SpriteOffset. Note that these coordinates assume the Leg being oriented horizontally as sprites for them are.

StartOffset

Used in the various LimbPath animation definitions, this specifies a target coordinate for the Limb to move to.

HolsterOffset

Not commonly used, if at all. Cortex Command currently does not "holster" any items when unequipped. Appears in both AHuman and ACRocket definitions.


OpenOffset

Used by doors to specify where the "door" part moves to when it opens.

ClosedOffset

Used by doors to specify where the "door" part moves to when the door is closed.

Personal tools