Skip to navigation

Lander on the Acorn Archimedes

Maths (Geometry): MultiplyVectorByMatrix

Name: MultiplyVectorByMatrix [Show more] Type: Subroutine Category: Maths (Geometry) Summary: Multiply a 3D vector by the rotation matrix in rotationMatrix, if the object is a rotating object
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * DrawObject (Part 2 of 5) calls MultiplyVectorByMatrix * DrawObject (Part 3 of 5) calls MultiplyVectorByMatrix

If the object currently being processed is static (i.e. bit 0 of objectFlags is clear), then this routine simply returns the vector in R0 unchanged. If the object is a rotating object, then this routine multiplies the vector at R0 by the rotation matrix at rotationMatrix and store the result at the address in R1: [ R1 ] [ R0 ] [ R1+4 ] = rotationMatrix . [ R0+4 ] [ R1+8 ] [ R0+8 ] [ xNoseV xRoofV xSideV ] [ R0 ] = [ yNoseV yRoofV ySideV ] . [ R0+4 ] [ zNoseV zRoofV zSideV ] [ R0+8 ] So this rotates a coordinate by the object's rotation matrix (i.e. by each of the object's orientation vectors).
Arguments: R0 The address of the vector to multiply R1 The address to store the result
Returns: [R1 R1+4 R1+8] The result of the multiplication as a vector
.MultiplyVectorByMatrix LDRB R2, [R11, #objectFlags] \ If bit 0 of objectFlags is clear then this TST R2, #%00000001 \ object is static and does not rotate, so LDMEQIA R0, {R2-R4} \ simply set the following so we do not STMEQIA R1, {R2-R4} \ apply the rotation matrix: MOVEQ PC, R14 \ \ [ R1 ] [ R0 ] \ [ R1+4 ] = [ R0+4 ] \ [ R1+8 ] [ R0+8 ] \ \ and return from the subroutine STMFD R13!, {R6-R7, R14} \ Store the registers that we want to use on \ the stack so they can be preserved ADD R2, R11, #rotationMatrix \ Set R2 to the address of the rotation \ matrix at rotationMatrix, which contains \ the object's rotation matrix BL GetDotProduct \ Set R1 = R2 . R0, so: STR R3, [R1] \ BL GetDotProduct \ [R1 ] [ R2 R2+4 R2+8 ] [R0 ] STR R3, [R1, #4] \ [R1+4] = [ R2+12 R2+16 R2+20 ] . [R0+4] BL GetDotProduct \ [R1+8] [ R2+24 R2+28 R2+32 ] [R0+8] STR R3, [R1, #8] \ \ which is the result we want LDMFD R13!, {R6-R7, PC} \ Retrieve the registers that we stored on \ the stack and return from the subroutine