OverviewThis page is an explanation of how collision normals are calculated in Zelda 64. If you're not familiar with vector mathematics then you should read a little on the subject first.I'm writing this purely so people who read it will understand the maths used to calculate the normals and I don't expect you to even try to do it by hand unless using it as an exercise for practising using vectors. To see an example of a program that does this, go here, download and take a look at the (slightly messy) source. Step 1: Finding the collision headerNot a complicated task. Simply follow the pointer in the scene header's 03 command to find it. Step 2: Getting the right informationWe'll need to know the location of the vertex array, number of triangles to draw and the location of the triangles' data, which can be found at 0x10, 0x14 and 0x18 within the collision header respectively. The addresses are stored as words, the first byte of which is the memory segment to use, and the number of triangles is stored as a halfword. Step 3: Reading the triangles' dataYou'll want to go to the offset of the first triangle's data to begin with and you'll see this: aaaa uuuu vvvv wwww xxxx yyyy zzzz dddd Where: a = triangle's collision type u = vertex 1 v = vertex 2 w = vertex 3 x = x-direction of the plane's normal y = y-direction of the plane's normal z = z-direction of the plane's normal d = perpendicular distance from the plane to the origin The last four halfwords are what we'll be calculating, so we only need u, v and w, which are the vertex numbers. To find the offsets of the vertex data, you'd go to the offset given by: vertex_array + ((vertex_number && 0x0FFF) * 6) The data at these offsets would be three signed halfwords - the vertex's x, y and z co-ordinates. Step 4: Finding a normal vector to the planeHere's the part you may not understand if you've not learned about vectors before. First it's necessary to get two vectors in our collision triangle's plane. How do we do this? Simply find the difference between vertex 1 and 2's positions, write down these three numbers as a vector and then do the same for vertex 2 and 3. Now we have enough information to calculate the normal to the plane in which our vectors lie by using the cross product. If you're not familiar with the cross product then I'd recommend going and reading up on it now. With that done you'll have the normal to the plane in vector form, but it's no use as it is; we need to write it as a unit vector first. Step 5: Using the unit normal vector and calculating the distanceOnce you have the unit normal vector calculated (divide each of the normal's components by its size - look it up if you don't know how) we can calculate the distance by using a simple equation. Using the cartesian form of a plane (ax + by + cz + d = 0) we can calculate the perpendicular distance to the origin as: d = -(ax + by + cz) Where a, b and c are the x, y and z components of the unit normal vector and x, y and z are the co-ordinates of any point in the plane (use one of the triangle's vertices). The result needs to be rounded to the nearest integer and must be between 32767 and -32768 inclusive. Step 6: x, y and z directions of the normal vectorSince there are only two bytes available for the directions, we can't store them as a standard float. Instead, Zelda 64 takes ±32767 (0x7FFF or 0x8001) to be ±1.0. To calculate these values, simply multiply the unit normal vector by 32767 and round it to the nearest integer. Step 7: Repeat for all collision trianglesSelf-explanatory. References |