Skip to navigation

Lander on the Acorn Archimedes

3D objects: DrawObject (Part 2 of 5)

Name: DrawObject (Part 2 of 5) [Show more] Type: Subroutine Category: 3D objects Summary: Process the object's vertices Deep dive: Drawing 3D objects Object blueprints Collisions and bullets
Context: See this subroutine in context in the source code References: No direct references to this subroutine in this source file
LDR R0, [R11, #objectData] \ Set R0 to the address of the blueprint \ for the object that is being drawn LDR R8, [R0] \ Set R8 to the first word of the blueprint, \ which contains the number of vertices ADD R9, R0, #16 \ Set R9 to the address of the vertices data \ in the blueprint, which appears from the \ 16th byte onwards ADD R10, R11, #vertexProjected \ Set R10 to the address of vertexProjected \ which is where we will store the screen \ coordinates of the projected vertices LDRB R1, [R0, #12] \ Set objectFlags to the fourth word of the STRB R1, [R11, #objectFlags] \ blueprint, which contains the object's \ flags \ We now iterate through the vertices in the \ blueprint, using R8 as a loop counter (as \ we set it above to the number of vertices) \ \ As we iterate through the vertices we \ rotate each one by the object's rotation \ matrix (to orientate the object properly) \ and project it onto the screen, saving the \ results in the vertexProjected table .dobj2 LDMIA R9!, {R2-R4} \ Load the coordinates of the next vertex \ from R9 into (R2, R3, R4), and update R9 \ to point to the vertex after that, ready \ for the next iteration ADD R0, R11, #xVertex \ Set R0 to the address of xVertex ADD R1, R11, #xVertexRotated \ Set R1 to the address of xVertexRotated STMIA R0, {R2-R4} \ Store the vertex coordinates in xVertex, \ so (xVertex, yVertex, zVertex) contains \ the vertex coordinates BL MultiplyVectorByMatrix \ If this object is a static object, then \ simply copy the vertex into xVertexRotated \ as follows: \ \ [xVertexRotated] [xVertex] \ [yVertexRotated] = [yVertex] \ [zVertexRotated] [zVertex] \ \ If this is a rotating object, then \ multiply the coordinates at R0 (i.e. the \ vertex coordinates at xVertex) by the \ rotation matrix in rotationMatrix, and \ store the results at R1 (i.e. the rotated \ coordinates at xVertexRotated): \ \ [xVertexRotated] [xVertex] \ [yVertexRotated] = rotMatrix . [yVertex] \ [zVertexRotated] [zVertex] \ \ So this rotates the vertex coordinates by \ the object's rotation matrix ADD R0, R11, #xObject \ Set R0 to the address of xObject BL AddVectorToVertices \ Call AddVectorToVertices to set: \ \ [xCoord] [xObject] [xVertexRotated] \ [yCoord] = [yObject] + [yVertexRotated] \ [zCoord] [zObject] [zVertexRotated] \ \ So (xCoord, yCoord, zCoord) contains the \ coordinates of this vertex in 3D space, \ using the game's coordinate system ADD R0, R11, #xCoord \ Set R0 to the address of xCoord BL ProjectVertexOntoScreen \ Project (xCoord, yCoord, zCoord) onto the \ screen, returning the results in (R0, R1) STMIA R10!, {R0-R1} \ Store (R0, R1) in vertexProjected and \ update R10 to point to the next coordinate \ in vertexProjected, ready for us to add \ the shadow's projected vertex next ADD R0, R11, #xCoord \ Set R0 to the address of xCoord BL GetLandscapeBelowVertex \ Get the landscape altitude below the \ vertex and return it in R0 STR R0, [R11, #yCoord] \ Set yCoord = R0, so (xCoord, yCoord, \ zCoord) now contains the coordinate on the \ landscape directly below the vertex \ \ We use this coordinate for the object's \ shadow, which we store in vertexProjected \ just after the normally projected vertex ADD R0, R11, #xCoord \ Set R0 to the address of xCoord BL ProjectVertexOntoScreen \ Project (xCoord, yCoord, zCoord) onto the \ screen, returning the results in (R0, R1) STMIA R10!, {R0-R1} \ Store (R0, R1) in vertexProjected and \ update R10 to point to the next coordinate \ in vertexProjected, ready for the next \ iteration LDR R14, [R10, #-12] \ Set R14 to the second coordinate from the \ previous projection, i.e. the y-coordinate \ of the projected vertex (so that's the \ object rather than the shadow) CMP R14, R1 \ If R14 >= R1 then the y-coordinate of the MVNHS R14, #0 \ object is bigger than the y-coordinate of STRHSB R14, [R11, #crashedFlag] \ the shadow, which means the object is \ lower down the screen than its shadow \ \ This can only happen if the object has \ "passed through" the ground, so set \ crashedFlag to &FF to indicate that the \ object has crashed SUBS R8, R8, #1 \ Decrement the loop counter, which keeps \ track of the number of vertices we have \ processed BNE dobj2 \ Loop back to dobj2 to move on to the next \ vertex, until we have processed them all \ We now move on to processing the object's \ face data so we can draw the visible faces