| 182 | } |
| 183 | |
| 184 | void Mat4::createBillboardHelper(const Vec3& objectPosition, |
| 185 | const Vec3& cameraPosition, |
| 186 | const Vec3& cameraUpVector, |
| 187 | const Vec3* cameraForwardVector, |
| 188 | Mat4* dst) |
| 189 | { |
| 190 | Vec3 delta(objectPosition, cameraPosition); |
| 191 | bool isSufficientDelta = delta.lengthSquared() > MATH_EPSILON; |
| 192 | |
| 193 | dst->setIdentity(); |
| 194 | dst->m[3] = objectPosition.x; |
| 195 | dst->m[7] = objectPosition.y; |
| 196 | dst->m[11] = objectPosition.z; |
| 197 | |
| 198 | // As per the contracts for the 2 variants of createBillboard, we need |
| 199 | // either a safe default or a sufficient distance between object and camera. |
| 200 | if (cameraForwardVector || isSufficientDelta) |
| 201 | { |
| 202 | Vec3 target = isSufficientDelta ? cameraPosition : (objectPosition - *cameraForwardVector); |
| 203 | |
| 204 | // A billboard is the inverse of a lookAt rotation |
| 205 | Mat4 lookAt; |
| 206 | createLookAt(objectPosition, target, cameraUpVector, &lookAt); |
| 207 | dst->m[0] = lookAt.m[0]; |
| 208 | dst->m[1] = lookAt.m[4]; |
| 209 | dst->m[2] = lookAt.m[8]; |
| 210 | dst->m[4] = lookAt.m[1]; |
| 211 | dst->m[5] = lookAt.m[5]; |
| 212 | dst->m[6] = lookAt.m[9]; |
| 213 | dst->m[8] = lookAt.m[2]; |
| 214 | dst->m[9] = lookAt.m[6]; |
| 215 | dst->m[10] = lookAt.m[10]; |
| 216 | } |
| 217 | } |
| 218 | |
| 219 | // void Mat4::createReflection(const Plane& plane, Mat4* dst) |
| 220 | // { |
nothing calls this directly
no test coverage detected