void arbitraryNormal(AffVector& normal) const; // to "this" AffVector cross(const AffVector& rhs) const; // return this x rhs void decompose(const AffVector& arbitraryVector, // with respect to "this" AffVector& parallel, AffVector& perpendicular) const; double dot(const AffVector& rhs) const; // return this . rhs double length() const; // of "this" double lengthSquared() const; // of "this" // In the following two "normalize" methods, the return value is the length // of "this" vector before normalization. For example, for |v| > eps: // double L = v.normalize(); // is equivalent to: // double L = v.length(); // v = v / L; double normalize(); // "this" (Unlike all the other methods in 1.b, "this" gets modified) double normalizeToCopy(AffVector& normalizedCopy) const;
In the first two:
void coordinateSystemFromUW(AffVector& U, AffVector& V, AffVector& W); void coordinateSystemFromVW(AffVector& U, AffVector& V, AffVector& W); AffVector cross(const AffVector& v1, const AffVector& v2); double dot(const AffVector& v1, const AffVector& v2);
const AffVector xu; // (1, 0, 0) - in your code, you reference this as: "cryph::AffVector::xu" const AffVector yu; // (0, 1, 0) const AffVector zu; // (0, 0, 1) const AffVector zeroVector;
double distanceSquaredTo(const AffPoint& P) const; // distance squared from "this" to "P" double distanceTo(const AffPoint& P) const; // distance from "this" to "P" void toCylindrical(double& r, double& theta, double& z) const; void toSpherical(double& rho, double& theta, double& phi) const;
AffPoint fromCylindrical(double r, double theta, double z); AffPoint fromSpherical(double rho, double theta, double phi);
const AffPoint origin; // e.g., in your code, you reference this as: "cryph::AffPoint::origin" const AffPoint xAxisPoint; // (1, 0, 0) const AffPoint yAxisPoint; // (0, 1, 0) const AffPoint zAxisPoint; // (0, 0, 1)
Transformation matrices are used to define view transformations for OpenGL (e.g., MC→EC; EC→LDS), but they can also be used to transform model geometry (e.g., MC→MC). We have already seen the cryph::Matrix4x4 class methods for creating view transformation matrices. Here we focus on methods that create other general modeling transformations.
For example, instead of creating our general Block as in 2.d, we may define it in canonical position and orientation (e.g., almost exactly as we first saw it in MandM), then create translation and/or rotation and/or scale transformations to place it where we want it in our MC space. Doing so typically requires that we transform both points and (normal) vectors. We will generally create 4x4 matrices for these transformations. Be sure you carefully declare normal vectors as cryph::AffVector and points as cryph::AffPoint because the overloaded matrix operators behave differently (as they must) when applied to points versus vectors. See, for example, 3.b.
Like the view transformation matrices we saw earlier (lookAt, perspective, et al.), all of the following are class method prototypes in class Matrix4x4. They are all "factory methods" that return matrices built as specified.
cryph::Matrix4x4 M = …; cryph::AffPoint myVector = …; … M * myVector …; // You will get unexpected results!!!
Instead, be sure you do:
cryph::Matrix4x4 M = …; cryph::AffVector myVector = …; … M * myVector …; // OK now!
void sendToGPU_AsFloatArray(cryph::AffPoint* points, int numPoints) { float* ptsAsFloat = new float[3*numPoints]; for (int i=0 ; i<numPoints ; i++) points[i].aCoords(ptsAsFloat, 3*i); // NOTE: "3*i" when passing as float* int numBytes = 3 * numPoints * sizeof(float); glBufferData(GL_ARRAY_BUFFER, numBytes, ptsAsFloat, GL_STATIC_DRAW); delete [] ptsAsFloat; }
Equivalently, you can send as a vec3 array:
void sendToGPU_AsVec3Array(cryph::AffPoint* points, int numPoints) { typedef float vec3[3]; vec3* ptsAsVec3 = new vec3[numPoints]; for (int i=0 ; i<numPoints ; i++) points[i].aCoords(ptsAsVec3, i); // NOTE: "i" when passing as vec3* int numBytes = numPoints * sizeof(vec3); glBufferData(GL_ARRAY_BUFFER, numBytes, ptsAsVec3, GL_STATIC_DRAW); delete [] ptsAsVec3; }
Regardless of how you send them, don't forget you also need to establish glVertexAttribPointer and glEnableVertexAttribArray properly.
cryph::Matrix4x4 mc_ec, ec_lds; ModelView::getMatrices(mc_ec, ec_lds); float m[16]; glUniformMatrix4fv(shaderIF->ppuLoc("mc_ec"), 1, false, mc_ec.extractColMajor(m)); glUniformMatrix4fv(shaderIF->ppuLoc("ec_lds"), 1, false, ec_lds.extractColMajor(m));