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 poly based surfaces.

Poly-based Collision

Polygon based collision detection is managed primarily by z_bgcheck.c. Follows the Collision Mesh format. Most meshes are stored in object files, rather than actor files like above.

Poly Lookup Table

Global Context + 0x7C0 is the address of the struct managing background collision information.

00 = ptr to scene collision mesh
04 = float[3] minimum x,y,z for scene bounding box
10 = float[3] maximum x,y,z for scene bounding box
1C = int[3] x,y,z CollisionPoly lookup table length
28 = float[3] x,y,z "unit size" factor for CollisionPoly lookup table
34 = float[3] x,y,z "inverse unit size" for CollisionPoly lookup table
40 = ptr to CollisionPoly lookup table, variable length, 0x06 bytes per record. 
   //record struct
   /* 0x00 */ short floorsId;   //CollisionPolyLink table index
   /* 0x02 */ short wallsId;    //CollisionPolyLink table index
   /* 0x04 */ short ceilingsId; //CollisionPolyLink table index
44 = short, Max Records in CollisionPolyLink table
46 = short, Number of Records Reserved in 0x48 table
48 = ptr, CollisionPolyLink table, 0x04 bytes per record
   //record struct
   /* 0x00 */ short polyId;
   /* 0x02 */ short next; //Next CollisionPolyLink table index
4C = ptr, CollisionPoly has been tested table, 1 byte per record, one record per poly defined in the scene mesh

In order to optimize collision detection, the scene mesh is subdivided into volumes, typically into 10 by 4 by 10 sections. Polys that cross within each section are categorized into floors, walls, and ceilings (likely based on their unit normals), and sorted into a linked list ordered by the polygon's lowest point (low y to high).

Poly Mesh Actors

Actors can have mesh-based collisions as well. 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 + 0x54 is the start address of the first actor mesh record. Each record is 0x64 bytes, as seen below. Global Context + 0x1B9C is an array of halfwords storing whether an actor mesh is loaded or not.

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.

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.

Name Purpose
AT Attack
AC Attack Checker
OT  ?

Group AT will be collided into group AC. I believe group OT will be collided amongst themselves.

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

For some old notes, see Notes/Collision.