void RotatePointAroundVector( vec3_t &dst, const vec3_t &dir, const vec3_t &point, float degrees ) { float m[3][3]; float im[3][3]; float zrot[3][3]; float tmpmat[3][3]; float rot[3][3]; int i; vec3_t vr, vup, vf; vf[0] = dir[0]; vf[1] = dir[1]; vf[2] = dir[2]; PerpendicularVector( vr, dir ); //CrossProduct( vr, vf, vup ); vup = CrossProduct( vr, vf ); m[0][0] = vr[0]; m[1][0] = vr[1]; m[2][0] = vr[2]; m[0][1] = vup[0]; m[1][1] = vup[1]; m[2][1] = vup[2]; m[0][2] = vf[0]; m[1][2] = vf[1]; m[2][2] = vf[2]; memcpy( im, m, sizeof( im ) ); im[0][1] = m[1][0]; im[0][2] = m[2][0]; im[1][0] = m[0][1]; im[1][2] = m[2][1]; im[2][0] = m[0][2]; im[2][1] = m[1][2]; memset( zrot, 0, sizeof( zrot ) ); zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F; zrot[0][0] = cos( DEG2RAD( degrees ) ); zrot[0][1] = sin( DEG2RAD( degrees ) ); zrot[1][0] = -sin( DEG2RAD( degrees ) ); zrot[1][1] = cos( DEG2RAD( degrees ) ); R_ConcatRotations( m, zrot, tmpmat ); R_ConcatRotations( tmpmat, im, rot ); for ( i = 0; i < 3; i++ ) { dst[i] = rot[i][0] * point[0] + rot[i][1] * point[1] + rot[i][2] * point[2]; } }
/** * @brief Rotate a point around a given vector * @param[in] dir The vector around which to rotate * @param[in] point The point to be rotated * @param[in] degrees How many degrees to rotate the point by * @param[out] dst The point after rotation * @note Warning: @c dst must be different from @c point (otherwise the result has no meaning) * @pre @c dir must be normalized */ void RotatePointAroundVector (vec3_t dst, const vec3_t dir, const vec3_t point, float degrees) { float m[3][3]; float im[3][3]; float zrot[3][3]; float tmpmat[3][3]; float rot[3][3]; int i; vec3_t vr, vup, vf; vf[0] = dir[0]; vf[1] = dir[1]; vf[2] = dir[2]; PerpendicularVector(vr, dir); CrossProduct(vr, vf, vup); m[0][0] = vr[0]; m[1][0] = vr[1]; m[2][0] = vr[2]; m[0][1] = vup[0]; m[1][1] = vup[1]; m[2][1] = vup[2]; m[0][2] = vf[0]; m[1][2] = vf[1]; m[2][2] = vf[2]; memcpy(im, m, sizeof(im)); im[0][1] = m[1][0]; im[0][2] = m[2][0]; im[1][0] = m[0][1]; im[1][2] = m[2][1]; im[2][0] = m[0][2]; im[2][1] = m[1][2]; OBJZERO(zrot); /* now prepare the rotation matrix */ zrot[0][0] = cos(degrees * torad); zrot[0][1] = sin(degrees * torad); zrot[1][0] = -sin(degrees * torad); zrot[1][1] = cos(degrees * torad); zrot[2][2] = 1.0F; R_ConcatRotations(m, zrot, tmpmat); R_ConcatRotations(tmpmat, im, rot); for (i = 0; i < 3; i++) { dst[i] = DotProduct(rot[i], point); } }
void RotatePointAroundVector( Coord *dst, Coord dir, Coord point, float degrees ) { float m[3][3]; float im[3][3]; float zrot[3][3]; float tmpmat[3][3]; float rot[3][3]; Coord vr, vup, vf; vf.x = dir.x; vf.y = dir.y; vf.z = dir.z; PerpendicularVector( &vr, dir ); CrossProduct( vr, vf, &vup ); m[0][0] = vr.x; m[1][0] = vr.y; m[2][0] = vr.z; m[0][1] = vup.x; m[1][1] = vup.y; m[2][1] = vup.z; m[0][2] = vf.x; m[1][2] = vf.y; m[2][2] = vf.z; memcpy( im, m, sizeof( im ) ); im[0][1] = m[1][0]; im[0][2] = m[2][0]; im[1][0] = m[0][1]; im[1][2] = m[2][1]; im[2][0] = m[0][2]; im[2][1] = m[1][2]; memset( zrot, 0, sizeof( zrot ) ); zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F; zrot[0][0] = cos( ( degrees*DEGTORAD ) ); zrot[0][1] = sin( ( degrees*DEGTORAD ) ); zrot[1][0] = -sin( ( degrees*DEGTORAD ) ); zrot[1][1] = cos( ( degrees*DEGTORAD ) ); R_ConcatRotations( m, zrot, tmpmat ); R_ConcatRotations( tmpmat, im, rot ); dst->x = rot[0][0] * point.x + rot[0][1] * point.y + rot[0][2] * point.z; dst->y = rot[1][0] * point.x + rot[1][1] * point.y + rot[1][2] * point.z; dst->z = rot[2][0] * point.x + rot[2][1] * point.y + rot[2][2] * point.z; }
/* ================ R_RotateBmodel ================ */ void R_RotateBmodel (void) { float angle, s, c, temp1[3][3], temp2[3][3], temp3[3][3]; // TODO: should use a look-up table // TODO: should really be stored with the entity instead of being reconstructed // TODO: could cache lazily, stored in the entity // TODO: share work with R_SetUpAliasTransform // yaw angle = currententity->angles[YAW]; angle = angle * (float) M_PI*2 / 360; s = (float)sin(angle); c = (float)cos(angle); temp1[0][0] = c; temp1[0][1] = s; temp1[0][2] = 0; temp1[1][0] = -s; temp1[1][1] = c; temp1[1][2] = 0; temp1[2][0] = 0; temp1[2][1] = 0; temp1[2][2] = 1; // pitch angle = currententity->angles[PITCH]; angle = angle * (float)M_PI*2 / 360; s = (float)sin(angle); c = (float)cos(angle); temp2[0][0] = c; temp2[0][1] = 0; temp2[0][2] = -s; temp2[1][0] = 0; temp2[1][1] = 1; temp2[1][2] = 0; temp2[2][0] = s; temp2[2][1] = 0; temp2[2][2] = c; R_ConcatRotations (temp2, temp1, temp3); // roll angle = currententity->angles[ROLL]; angle = angle * (float)M_PI*2 / 360; s = (float)sin(angle); c = (float)cos(angle); temp1[0][0] = 1; temp1[0][1] = 0; temp1[0][2] = 0; temp1[1][0] = 0; temp1[1][1] = c; temp1[1][2] = s; temp1[2][0] = 0; temp1[2][1] = -s; temp1[2][2] = c; R_ConcatRotations (temp1, temp3, entity_rotation); // // rotate modelorg and the transformation matrix // R_EntityRotate (modelorg); R_EntityRotate (vpn); R_EntityRotate (vright); R_EntityRotate (vup); R_TransformFrustum (); }