Collision

From CloudModding OoT Wiki
Jump to: navigation, search

Actors appear to use one of two types of collision models, simple bodies (cylinders, simplistic shapes), and high-poly based surfaces.

Simple Body Collision

Some collision testing is handled by using very simplistic geometrical shapes. Cylinders are used most often, typically to represent the body of something. Triangles are typically used for attacks. Link's shield uses a quad. In order to perform collision testing, an entity will "subscribe" a simple body to one of three collision "category" on every frame (game update). After all actors have been processed, collision checks will processed by testing a body against all others within it's subscribed category.

Name Purpose
AT Attack?
AC  ?
OT  ?

Global Context

//1DA300, start of collision array AT (Gohma, Skullwalltulas)
0x11E60 short	//number of elements to process this frame
0x11E64 ptr 	//first element in array 

//1DA3CC, start of collision array AC (more inclusive, seems to follow actor category order, only one with 3d heart actor)
0x11F2C int 	//number of elements to process this frame

//1DA4C0, start of collision array OT (contains the most actors in Deku Tree)
0x12020

Cylinder Body Collision Struct (Overlay)

This is how the data is stored on file. Addresses are NTSC 1.0

//803AAE7C for Link
//0x2C bytes long, not the only type of collision struct
0x00	byte	//?
0x01	byte	//?
0x02	byte	//?
0x03	byte	//?
0x04	byte	//?
0x05	byte	//?
0x08	byte	//?
0x0C	int	//? (FFCF FFFF, used to compare to Link's FFCF FFFF?)
0x10	byte	//?
0x11	byte	//Damage dealt when touched
0x14	int 	//? (FFCF FFFF)
0x18	byte	//?
0x19	byte	//?
0x1C	byte	//?
0x1D	byte	//?
0x1E	byte	//?
0x20	int?	//Contains cylinder radius or diameter
0x24	int?	//?
0x28	int?	//? (thought this struct was only 0x24 bytes)

Cylinder Body Collision Struct (Actor Instance)

This is the in-memory struct used for actor collision related stuff. In NTSC 1.0 at least, this struct is 0x4C bytes long

//To simplify, CSO = Collision Struct (Overlay) reference, the struct above
//801DAEB8 for Link
0x00	ptr 	//Actor Instance
0x08	ptr		//Colliding Actor Instance?
0x10	byte	//CSO 0x01
0x11	byte	//CSO 0x02 //if & 0x0002, is detecting a Deku Nut hit?
0x12	byte	//CSO 0x03, bitwise-and compared to opposing collision's 0x13 byte
0x13	byte	//CSO 0x04, bitwise-and compared to opposing collision's 0x12 byte
0x14	byte	//CSO 0x00
0x15	byte	//CSO 0x05, used to reference function pointer, start location at 800EFB4C.
				//Basically, on left compare to right, left's value * 0x10 + right's value * 0x04 = pointer look up
0x18	int 	//CSO 0x0C
0x1C	byte	//CSO 0x10
0x1D	byte	//CSO 0x11, Damage Dealt when touched
0x20	int 	//CSO 0x14 (FFCF FFFF)
0x24	byte	//CSO 0x18
0x25	byte	//CSO 0x19
0x2C	byte	//CSO 0x08
0x2D	byte	//CSO 0x1C
0x2E	byte	//CSO 0x1D
0x2F	byte	//CSO 0x1E
0x40	short	//CSO 0x20 Cylinder radius or diameter
0x42	short	//CS0 0x22 Cylinder Height
0x44	short	//CSO 0x24 
0x46	short	//Cylinder X
0x48	short	//Cylinder Y
0x4A	short	//Cylinder Z


Older Notes

int external_func_8005C050(void * ctxt, void * idk, void * a, Collision_Header * a3)
// Argument 3 (a3) contains a pointer to a structure of this format:

JAL 0x8005BB48 // Sets up the collision for the hitbox
OR A2, S1, R0 // A2 = Current hitbox address

typedef struct
{
u8 u0
u8 u1
u8 u2
u8 u3
u8 u4
u8 pad[5] // Always "00 00 00 00 00" ?
u16 no_hitbox // Number of hitboxes... changing this to 0 will disable the actor's collision
u32 ptr_hitbox // Pointer to hitbox data
} Collision_Header;

Wolfos: (data_80B37A20)
09
11
0D
39
10
00 00 00 00 00
00 04 <--- Number of hitboxes
80 B3 79 90 <--- Pointer to hitbox data

Queen Ghoma: (data_8091B034)
03 
11 
09 <--- Setting to not 9 makes it impossible to stun her?
09 
10 
00 00 00 00 00 
00 0D <--- Number of hitboxes
80 91 AE 60 <--- Pointer to hitbox data

The damage done by a specific hitbox and its attributes are in the following format (0x24 bytes in length):

AA 00 00 00  XX XX XX XX  EE DD 00 00  YY YY YY YY  00 00 00 00  BB HH CC 00  FF 00 00 00  00 00 00 00  00 LL 00 64

AA : Unknown
XX XX XX XX : Usually "FF CF FF FF"... Perhaps normals? I can see this as being the direction to deal/receive damage
EE : Effect of damage (fire, ice, electric, stun, etc)
    00 = None
    01 = Fire
    02 = Ice
    03 = Electricity
    04 = Knockback

DD : Amount of damage (when hitting link)
YY YY YY YY : Usually "FF CF FF FF"... Perhaps normals? I can see this is being the direction to deal/receive damage
BB : Unknown
HH : Seems to have something to do with being hookshotable... Change to 05 to make the hitbox hookshotable
CC : Unknown
FF : Unknown
LL : Length of damage collision (allows an attack to reach further away)

Wolfos: (data_80B37990)
01 : 00 00 00 00 FF CF FF FF 00 04 00 00 00 00 00 00 00 00 00 00 01 00 00 00 0F 00 00 00 00 00 00 00 00 0F 00 64
02 : 00 00 00 00 FF CF FF FF 00 04 00 00 00 00 00 00 00 00 00 00 01 00 00 00 15 00 00 00 00 00 00 00 00 0F 00 64
03 : 01 00 00 00 00 00 00 00 00 00 00 00 FF C1 FF FF 00 00 00 00 00 05 01 00 11 00 03 20 00 00 00 00 00 19 00 64
04 : 01 00 00 00 00 00 00 00 00 00 00 00 FF C1 FF FF 00 00 00 00 00 05 01 00 0C 00 00 00 00 00 00 00 00 1E 00 64

Queen Ghoma: (data_8091AE60) (0x5450)
01 : 03 00 00 00 FF CF FF FF 00 08 00 00 FF CF FF FF 00 00 00 00 01 01 01 00 05 00 00 00 00 00 04 B0 00 14 00 64
02 : 02 00 00 00 FF CF FF FF 00 08 00 00 FF CF FF FF 00 00 00 00 01 01 01 00 0B 00 00 00 00 00 00 00 00 14 00 64
03 : 02 00 00 00 FF CF FF FF 00 08 00 00 FF CF FF FF 00 00 00 00 01 01 01 00 0C 00 00 00 00 00 00 00 00 0F 00 64
04 : 02 00 00 00 FF CF FF FF 00 08 00 00 FF CF FF FF 00 00 00 00 01 01 01 00 0D 00 00 00 00 00 00 00 00 0C 00 64
05 : 02 00 00 00 FF CF FF FF 00 08 00 00 FF CF FF FF 00 00 00 00 01 01 01 00 0E 00 00 00 00 00 00 00 00 19 00 64
06 : 02 00 00 00 FF CF FF FF 00 08 00 00 FF CF FF FF 00 00 00 00 01 01 01 00 16 00 00 00 00 00 00 00 00 1E 00 64
07 : 02 00 00 00 FF CF FF FF 00 08 00 00 FF CF FF FF 00 00 00 00 01 01 01 00 17 00 00 00 00 00 00 00 00 0F 00 64
08 : 02 00 00 00 FF CF FF FF 00 08 00 00 FF CF FF FF 00 00 00 00 01 01 01 00 1D 00 00 00 00 00 00 00 00 0F 00 64
09 : 02 00 00 00 FF CF FF FF 00 08 00 00 FF CF FF FF 00 00 00 00 01 01 01 00 39 00 00 00 00 00 00 00 00 14 00 64
10 : 02 00 00 00 FF CF FF FF 00 08 00 00 FF CF FF FF 00 00 00 00 01 01 01 00 40 00 00 00 00 00 00 00 00 14 00 64
11 : 02 00 00 00 FF CF FF FF 00 08 00 00 FF CF FF FF 00 00 00 00 01 01 01 00 4A 00 00 00 00 00 00 00 00 1E 00 64
12 : 02 00 00 00 FF CF FF FF 00 08 00 00 FF CF FF FF 00 00 00 00 01 01 01 00 4B 00 00 00 00 00 00 00 00 0F 00 64
13 : 02 00 00 00 FF CF FF FF 00 08 00 00 FF CF FF FF 00 00 00 00 01 01 01 00 51 00 00 00 00 00 00 00 00 0F 00 64

Poly-based Collision

Follows the Collision Format (Scenes) format. Most meshes are stored in object files, rather than actor files like above.

Global Context

Actors using this type of collision model load data into the Global Context. The game engine can handle up to a maximum of 50 meshes, plus the scene file's mesh (which is assigned index 50 or 0x32).

Global Context + 0x7C0 is where the scene's mesh is stored. Global Context + 0x1B9C is an array of halfwords storing whether an actor mesh is loaded or not. Global Context + 0x7C0 + 0x54 is where the first actor mesh data is stored. Each record is 0x64 bytes:

Offset Type Description
0x0000 Ptr Actor Instance
0x0004 Ptr Collision Mesh Pointer
0x0014 float[3] Actor x,y,z scale 1
0x0020 short[3] Actor x,y,z rotation 1
0x0028 float[3] Actor x,y,z coordinates 1
0x0034 float[3] Actor x,y,z scale 2
0x0040 short[3] Actor x,y,z rotation 2
0x0048 float[3] Actor x,y,z coordinates 2

Mesh Locations

"Dep. Actor" should be the Actor Id of the actor that uses the mesh. Offsets are for NTSC 1.0, but offsets for object files should almost always work regardless of version.

Type Id Offset Dep. Actor
Actor 0106 0024C0 0106
Actor 016B 004C20 016B
Object 0002 0041B0 00D0
Object 0003 004E98 00FF
Object 0003 005FB8 012A
Object 000E 005FC8 000A
Object 0019 0250A8 0059
Object 001C 01D9D0 002E
Object 002A 000E94 003E
Object 002B 001DDC 003F
Object 002B 003CE0 0058
Object 002B 004F30 005C
Object 002C 00DA10 0040
Object 002C 00E2CC 006F
Object 002C 00D054 0041
Object 002F 0005E0 004A
Object 002F 000280 004A
Object 0036 006460 000F
Object 0038 000118 0054
Object 0040 001830 005A
Object 0040 000A1C 005A
Object 0059 0003F0 0064
Object 0059 003590 0064
Object 0059 000998 0064
Object 0059 0073F0 01BB
Object 0059 001DE8 01BA
Object 0061 000658 006E
Object 0069 00A938 00F7
Object 0069 010E10 00F7
Object 0069 0131C4 00F7
Object 0069 004780 00AE
Object 0069 0044D0 00AE
Object 006A 000EE8 00D5
Object 006B 002594 01C7
Object 0070 0043D0 0068
Object 0072 0035F8 0087
Object 0072 00221C 0086
Object 0072 0063B8 0088
Object 0072 0089E0 00E3
Object 0072 0087AC 0089
Object 0074 0039D4 01A8
Object 0076 0000C0 0026
Object 008D 000C2C 00BE
Object 008D 001830 00AE
Object 0096 005CF8 00E6
Object 0096 005580 00C8
Object 0096 005048 00C8
Object 0096 008CE0 00C8
Object 0099 007860 0093
Object 009A 00169C 0092
Object 009C 000D68 00AC
Object 00A1 0128D8 009C
Object 00A1 0133EC 009C
Object 00A2 000428 009D
Object 00AE 00283C 00B8
Object 00AF 002154 015C
Object 00AF 000368 01C3
Object 00AF 000534 01C4
Object 00AF 00261C 00B9
Object 00AF 002FE4 00B9
Object 00B1 000A38 01A9
Object 00E2 0180F8 0166
Object 00F0 000348 0107
Object 00F0 0004D0 00F8
Object 00F1 0004A8 018E
Object 00F9 00075C 0103
Object 0100 001438 0108
Object 0112 000C98 011F
Object 011C 000730 012D
Object 011C 000578 012D
Object 0125 007564 0136
Object 0130 000DB8 0148
Object 0161 000918 018D
Object 0161 0012C0 018D
Object 0162 00238C 0191
Object 0162 0011EC 0190
Object 0166 000AF0 0194
Object 0166 000908 0194
Object 016C 000D48 0169
Object 016C 001430 0169
Object 016F 001A58 019F
Object 0170 000B70 01A0
Object 0181 001C58 019D
Object 0181 001DA8 0100
Object 018A 000118 0059
Object 0190 000B30 01D1

Just look up any function calls to external_func_8005C050 in a disassembled actor file and you're sure to find what you need by looking at argument 3 which contains what seems to be the actor's hitbox header.