void RotateManipulator::updateCircleTransforms () { Vector3 localViewpoint(matrix4_transformed_direction(m_pivot.m_worldSpace.getTransposed(), m_pivot.m_viewpointSpace.z().getVector3())); m_circle_x_visible = !vector3_equal_epsilon(g_vector3_axis_x, localViewpoint, 1e-6f); if (m_circle_x_visible) { m_local2world_x = Matrix4::getIdentity(); m_local2world_x.y().getVector3() = g_vector3_axis_x.crossProduct(localViewpoint).getNormalised(); m_local2world_x.z().getVector3() = m_local2world_x.x().getVector3().crossProduct( m_local2world_x.y().getVector3()).getNormalised(); matrix4_premultiply_by_matrix4(m_local2world_x, m_pivot.m_worldSpace); } m_circle_y_visible = !vector3_equal_epsilon(g_vector3_axis_y, localViewpoint, 1e-6f); if (m_circle_y_visible) { m_local2world_y = Matrix4::getIdentity(); m_local2world_y.z().getVector3() = g_vector3_axis_y.crossProduct(localViewpoint).getNormalised(); m_local2world_y.x().getVector3() = m_local2world_y.y().getVector3().crossProduct( m_local2world_y.z().getVector3()).getNormalised(); matrix4_premultiply_by_matrix4(m_local2world_y, m_pivot.m_worldSpace); } m_circle_z_visible = !vector3_equal_epsilon(g_vector3_axis_z, localViewpoint, 1e-6f); if (m_circle_z_visible) { m_local2world_z = Matrix4::getIdentity(); m_local2world_z.x().getVector3() = g_vector3_axis_z.crossProduct(localViewpoint).getNormalised(); m_local2world_z.y().getVector3() = m_local2world_z.z().getVector3().crossProduct( m_local2world_z.x().getVector3()).getNormalised(); matrix4_premultiply_by_matrix4(m_local2world_z, m_pivot.m_worldSpace); } }
void TextureProjection::emitTextureCoordinates (std::size_t width, std::size_t height, Winding& w, const Vector3& normal, const Matrix4& localToWorld) { if (w.size() < 3) { return; } Matrix4 local2tex = m_texdef.getTransform((float) width, (float) height); { Matrix4 xyz2st; // we don't care if it's not normalised... basisForNormal(matrix4_transformed_direction(localToWorld, normal), xyz2st); matrix4_multiply_by_matrix4(local2tex, xyz2st); } Vector3 tangent(local2tex.getTransposed().x().getVector3().getNormalised()); Vector3 bitangent(local2tex.getTransposed().y().getVector3().getNormalised()); matrix4_multiply_by_matrix4(local2tex, localToWorld); for (Winding::iterator i = w.begin(); i != w.end(); ++i) { Vector3 texcoord = matrix4_transformed_point(local2tex, (*i).vertex); (*i).texcoord[0] = texcoord[0]; (*i).texcoord[1] = texcoord[1]; (*i).tangent = tangent; (*i).bitangent = bitangent; } }
void updateTransform () { m_transform.localToParent() = Matrix4::getIdentity(); m_transform.localToParent().translateBy(m_origin); m_ray.direction = matrix4_transformed_direction(matrix4_rotation_for_z(degrees_to_radians(m_angle)), Vector3(1, 0, 0)); m_transformChanged(); }
void TextureProjection::transformLocked (std::size_t width, std::size_t height, const Plane3& plane, const Matrix4& identity2transformed) { Vector3 normalTransformed(matrix4_transformed_direction(identity2transformed, plane.normal())); // identity: identity space // transformed: transformation // stIdentity: base st projection space before transformation // stTransformed: base st projection space after transformation // stOriginal: original texdef space // stTransformed2stOriginal = stTransformed -> transformed -> identity -> stIdentity -> stOriginal Matrix4 identity2stIdentity; basisForNormal(plane.normal(), identity2stIdentity); Matrix4 transformed2stTransformed; basisForNormal(normalTransformed, transformed2stTransformed); Matrix4 stTransformed2identity(matrix4_affine_inverse(matrix4_multiplied_by_matrix4(transformed2stTransformed, identity2transformed))); Vector3 originalProjectionAxis(matrix4_affine_inverse(identity2stIdentity).z().getVector3()); Vector3 transformedProjectionAxis(stTransformed2identity.z().getVector3()); Matrix4 stIdentity2stOriginal = m_texdef.getTransform((float) width, (float) height); Matrix4 identity2stOriginal(matrix4_multiplied_by_matrix4(stIdentity2stOriginal, identity2stIdentity)); double dot = originalProjectionAxis.dot(transformedProjectionAxis); if (dot == 0) { // The projection axis chosen for the transformed normal is at 90 degrees // to the transformed projection axis chosen for the original normal. // This happens when the projection axis is ambiguous - e.g. for the plane // 'X == Y' the projection axis could be either X or Y. Matrix4 identityCorrected = matrix4_reflection_for_plane45(plane, originalProjectionAxis, transformedProjectionAxis); identity2stOriginal = matrix4_multiplied_by_matrix4(identity2stOriginal, identityCorrected); } Matrix4 stTransformed2stOriginal = matrix4_multiplied_by_matrix4(identity2stOriginal, stTransformed2identity); setTransform((float) width, (float) height, stTransformed2stOriginal); m_texdef.normalise((float) width, (float) height); }
void render(RenderStateFlags state) const { Matrix4 mat = matrix4_rotation_for_euler_xyz_degrees(m_angles); arrow_draw(m_origin, matrix4_transformed_direction(mat, Vector3(1, 0, 0)), matrix4_transformed_direction(mat, Vector3(0, 1, 0)), matrix4_transformed_direction(mat, Vector3(0, 0, 1))); }