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; } }
brushsplit_t Winding_ClassifyPlane(const Winding& winding, const Plane3& plane) { brushsplit_t split; for(Winding::const_iterator i = winding.begin(); i != winding.end(); ++i) { ++split.counts[Winding_ClassifyDistance(plane3_distance_to_point(plane, (*i).vertex), ON_EPSILON)]; } return split; }
/// \brief Returns true if /// !flipped && winding is completely BACK or ON /// or flipped && winding is completely FRONT or ON bool Winding_TestPlane(const Winding& winding, const Plane3& plane, bool flipped) { const int test = (flipped) ? ePlaneBack : ePlaneFront; for(Winding::const_iterator i = winding.begin(); i != winding.end(); ++i) { if(test == Winding_ClassifyDistance(plane3_distance_to_point(plane, (*i).vertex), ON_EPSILON)) { return false; } } return true; }
void TextureProjection::fitTexture (std::size_t width, std::size_t height, const Vector3& normal, const Winding& w, float s_repeat, float t_repeat) { if (w.size() < 3) { return; } Matrix4 st2tex = m_texdef.getTransform((float) width, (float) height); // the current texture transform Matrix4 local2tex = st2tex; { Matrix4 xyz2st; basisForNormal(normal, xyz2st); matrix4_multiply_by_matrix4(local2tex, xyz2st); } // the bounds of the current texture transform AABB bounds; for (Winding::const_iterator i = w.begin(); i != w.end(); ++i) { Vector3 texcoord = matrix4_transformed_point(local2tex, (*i).vertex); aabb_extend_by_point_safe(bounds, texcoord); } bounds.origin.z() = 0; bounds.extents.z() = 1; // the bounds of a perfectly fitted texture transform AABB perfect(Vector3(s_repeat * 0.5, t_repeat * 0.5, 0), Vector3(s_repeat * 0.5, t_repeat * 0.5, 1)); // the difference between the current texture transform and the perfectly fitted transform Matrix4 matrix(Matrix4::getTranslation(bounds.origin - perfect.origin)); matrix4_pivoted_scale_by_vec3(matrix, bounds.extents / perfect.extents, perfect.origin); matrix4_affine_invert(matrix); // apply the difference to the current texture transform matrix4_premultiply_by_matrix4(st2tex, matrix); setTransform((float) width, (float) height, st2tex); m_texdef.normalise((float) width, (float) height); }