void Matrix4x4f::rotateDegrees(const float &angleDegrees, const Vector3f &axis) { float angleRadians = angleDegrees * DEG_TO_RAD; Matrix4x4f newMatrix; newMatrix.setAsRotationMatrix(angleRadians, axis); (*this) = newMatrix * (*this); }
void Md3Model::draw () const { Matrix4x4f m; // Draw the model renderFrameItpWithVertexArrays (_currFrame, _nextFrame, _interp); // Draw models linked to this one for (int i = 0; i < _header.num_tags; ++i) { if (!_links[i]) continue; const Quaternionf &qA = _qtags[_currFrame * _header.num_tags + i]->orient; const Quaternionf &qB = _qtags[_nextFrame * _header.num_tags + i]->orient; m.fromQuaternion (Slerp (qA, qB, _interp)); const Vector3f &currPos = _qtags[_currFrame * _header.num_tags + i]->origin; const Vector3f &nextPos = _qtags[_nextFrame * _header.num_tags + i]->origin; m.setTranslation ((currPos + _interp * (nextPos - currPos)) * _scale); glPushMatrix (); glMultMatrixf (m); _links[i]->draw (); glPopMatrix (); } }
Matrix4x4f BoneBridgeCAL3D::CalculateBoneSpaceTransform() const { Matrix4x4f boneSpaceTransform = Matrix4x4f::Identity(); // set up bone space geometry transform { // transform forward by half the box length const Vec3f& dimensions = GetDimensions(); boneSpaceTransform.SetTranslation(Vec3f(dimensions[Y] / 2.0f, 0.0f, 0.0f)); // set rotational offset (the inversion of the core bone absolute rotation) { CalCoreBone* coreBone = mpCalBone->getCoreBone(); CalQuaternion calRotAbsolute = coreBone->getRotationAbsolute(); calRotAbsolute.invert(); Quaternionf kernelRot = ConvertCAL3DtoKernel(calRotAbsolute); boneSpaceTransform.SetRotate(kernelRot); } } return boneSpaceTransform; }
Matrix4x4f BoneBridgeCAL3D::GetModelSpaceTransform() const { Matrix4x4f matrix = Matrix4x4f::Identity(); // update model space position { Vec3f kernelPosVec; const CalVector& calPosVec = mpCalBone->getTranslationAbsolute(); for (int i = 0; i < 3; ++i) { kernelPosVec[i] = calPosVec[i]; } matrix.SetTranslation(kernelPosVec); } // update model space orientation { Quaternionf kernelRotQuat; const CalQuaternion& calRotQuat = mpCalBone->getRotationAbsolute(); kernelRotQuat = ConvertCAL3DtoKernel(calRotQuat); matrix.SetRotate(kernelRotQuat); } return matrix; }
Matrix4x4f Matrix4x4f::transpose() const { Matrix4x4f transpose; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) transpose.set(j, i, get(i, j)); return transpose; }
void Matrix4x4f::translate(const Vector3f &translation) { Matrix4x4f newMatrix; newMatrix.setAsTranslationMatrix(translation); Matrix4x4f testMatrix; (*this) = newMatrix * (*this); }
void Camera::SetYaw(float y) { yaw = y; Matrix4x4f Rx = Matrix4x4f::RotationX(pitch); Matrix4x4f Ry = Matrix4x4f::RotationY(yaw); Matrix4x4f R = Ry * Rx; forward = R.TransformVector(Vector3f(0, 0, -1)); right = R.TransformVector(Vector3f(1, 0, 0)); up = R.TransformVector(Vector3f(0, 1, 0)); }
Matrix4x4f Matrix4x4f::scaleMatrix(const Vec3f &scale) { Matrix4x4f scaleMatrix; scaleMatrix.setIdentity(); scaleMatrix.set(0, 0, scale.x); scaleMatrix.set(1, 1, scale.y); scaleMatrix.set(2, 2, scale.z); return scaleMatrix; }
Matrix4x4f Matrix4x4f::translateMatrix(const Vec3f translation) { Matrix4x4f translateMatrix; translateMatrix.setIdentity(); translateMatrix.set(3, 0, translation.x); translateMatrix.set(3, 1, translation.y); translateMatrix.set(3, 2, translation.z); return translateMatrix; }
static void load_camera() { FILE* fp = fopen("camera.txt", "rt"); assert(fp); for (int i = 0; i < 16; i++) fscanf(fp, "%f", &cam_to_view.data()[i]); for (int i = 0; i < 16; i++) fscanf(fp, "%f", &cam_to_clip.data()[i]); fclose(fp); fprintf(stderr, "camera loaded from camera.txt\n"); }
void textureProjection(Matrix4x4f &mv) { Matrix4x4f inverseMV = Matrix4x4f::invertMatrix(mv); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glTranslatef(0.5f,0.5f,0.0f); //Bias glScalef(0.5f,0.5f,1.0f); //Scale glFrustum(-0.035,0.035,-0.035,0.035,0.1,1.9); //MV for light map glTranslatef(0.0f,0.0f,-1.0f); glMultMatrixf(inverseMV.getMatrix()); //Inverse ModelView glMatrixMode(GL_MODELVIEW); }
void CastorUtilsMatrixTest::MatrixInversionComparison() { for ( int i = 0; i < 10; ++i ) { Matrix4x4f mtx; glm::mat4 glm; randomInit( mtx.ptr(), &glm[0][0], 16 ); CT_EQUAL( mtx, glm ); Matrix4x4f mtxInv( mtx.getInverse() ); glm::mat4 glmInv( glm::inverse( glm ) ); CT_EQUAL( mtxInv, glmInv ); } }
void BoneBridgeCAL3D::SetModelSpaceTransform(const Matrix4x4f& modelSpaceTransform) const { // calculate the transform as relative to the parent bone Matrix4x4f localModelSpaceTransform = Matrix4x4f::Identity(); { // for now use absolute model space positioning localModelSpaceTransform = modelSpaceTransform; // divide by any existing parent's model space position if (const Bone* parent = GetParent()) { //const osg::Matrix parentTransform = ConvertKerneltoOSG(parent->GetModelSpaceTransform()); const Matrix4x4f parentTransform = parent->GetModelSpaceTransform(); // get inverse of parent transform const Matrix4x4f invParentTransform = parentTransform.Inverse(); localModelSpaceTransform *= invParentTransform; } } // now update the cal3d side from this new model space information #if WRITE_CAL3D_BONE_TRANSLATION // update model space position { Vec3f kernelPosVec = localModelSpaceTransform.GetTranslation(); CalVector calPosVec; for (int i = 0; i < 3; ++i) { calPosVec[i] = kernelPosVec[i]; } mpCalBone->setTranslation(calPosVec); // setting the relative position } #endif #if WRITE_CAL3D_BONE_ROTATION // update model space orientation { const Quaternionf& kernelRotQuat = localModelSpaceTransform.GetRotate(); CalQuaternion calRotQuat; calRotQuat = ConvertKerneltoCAL3D(kernelRotQuat); mpCalBone->setRotation(calRotQuat); // setting the relative orientation } #endif }
Matrix4x4f Matrix4x4f::rotateMatrixZ(float angle) { float cosOfAngle = std::cosf(angle); float sinOfAngle = std::sinf(angle); Matrix4x4f rotationMatrix; rotationMatrix.setIdentity(); rotationMatrix.set(0, 0, cosOfAngle); rotationMatrix.set(1, 0, sinOfAngle); rotationMatrix.set(0, 1, -sinOfAngle); rotationMatrix.set(1, 1, cosOfAngle); return rotationMatrix; }
Matrix4x4f Matrix4x4f::operator*(const Matrix4x4f &other) const { Matrix4x4f product; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { float sum = 0.0f; // jth row of this by ith column of other for (int d = 0; d < 4; d++) sum += get(d, j) * other.get(i, d); product.set(i, j, sum); } return product; }
//Default values void apply_default() { m_initial_transform_matrix.load_identity(); colId = -1; mass = 1; colWithIds = NULL; }
void textureProjection(Matrix4x4f &mv) { Matrix4x4f inverseMV = Matrix4x4f::invertMatrix(mv); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glTranslatef(0.5f,0.5f,0.0f); float wImg = textureImage[textureIndex-1].Width; float hImg = textureImage[textureIndex-1].Height; if (wImg < hImg) { glScalef(1.0f,(1.f*wImg)/hImg,1.0f); } else { glScalef((1.f*hImg)/wImg,1.0f,1.0f); } glFrustum(-0.035,0.035,-0.035,0.035,0.02,2.0); glMultMatrixf(inverseMV.getMatrix()); glMatrixMode(GL_MODELVIEW); }
bool Matrix4x4f::operator==(const Matrix4x4f &other) const { for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) { if (get(i, j) != other.get(i, j)) return false; } return true; }
MVP(const Matrix4x4f &modelMatrix, const Matrix4x4f &viewMatrix, const Matrix4x4f &projectionMatrix) { this->modelMatrix = modelMatrix; this->viewMatrix = viewMatrix; this->projectionMatrix = projectionMatrix; modelViewMatrix = viewMatrix * modelMatrix; modelViewMatrixForNormal = modelViewMatrix.inverse().transpose(); modelViewProjMatrix = projectionMatrix * modelViewMatrix; }
void renderDirectionalLightPass() { glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glCullFace(GL_FRONT); glUseProgram(directionalLightPass.program); Matrix4x4f identity = Matrix4x4f::identity(); glUniformMatrix4fv(directionalLightPass.modelMatrix, 1, GL_FALSE, identity.const_value_ptr()); glUniformMatrix4fv(directionalLightPass.viewMatrix, 1, GL_FALSE, identity.const_value_ptr()); glUniformMatrix4fv(directionalLightPass.projectionMatrix, 1, GL_FALSE, identity.const_value_ptr()); directionalLightPass.bindUniforms(); directionalLightPass.directionalLight.setDirectionalLight(directionalLight); pQuadMesh->Render(); glUseProgram(0); }
void textureProjection(Matrix4x4f &mv) { Matrix4x4f inverseMV = Matrix4x4f::invertMatrix(mv); glMatrixMode(GL_TEXTURE); glLoadIdentity(); glTranslatef(0.5f,0.5f,0.0f);//Bias float wImg = textureW[textureIndex-1]; float hImg = textureH[textureIndex-1]; if (wImg < hImg) { glScalef(1.0f,(1.f*wImg)/hImg,1.0f);//Scale } else { glScalef((1.f*hImg)/wImg,1.0f,1.0f);//Scale } glFrustum(-0.035,0.035,-0.035,0.035,0.02,2.0);//MV for light map //glTranslatef(0.0f,0.0f,-1.0f); glMultMatrixf(inverseMV.getMatrix());//Inverse ModelView glMatrixMode(GL_MODELVIEW); }
void Camera::LookUp(float angle) { if(pitch - angle > PI/2.0f - 0.1) { pitch = PI/2.0f - 0.1; } else if(pitch - angle < -PI/2.0f) { pitch = -PI/2.0f + 0.1; } else pitch -= angle; Matrix4x4f Rx = Matrix4x4f::RotationX(pitch); Matrix4x4f Ry = Matrix4x4f::RotationY(yaw); Matrix4x4f R = Ry * Rx; forward = R.TransformVector(Vector3f(0, 0, -1)); right = R.TransformVector(Vector3f(1, 0, 0)); up = R.TransformVector(Vector3f(0, 1, 0)); }
void renderLightVolume(const MVPPipeline &program, const PointLight &light) { Matrix4x4f modelMatrix = Matrix4x4f::identity(); modelMatrix = modelMatrix.translate(light.position); float scale = calcPointLightScale(light); modelMatrix = modelMatrix.scale({scale, scale, scale}); glUniformMatrix4fv(program.modelMatrix, 1, GL_FALSE, modelMatrix.const_value_ptr()); Matrix4x4f viewMatrix = camera.getMatrix(); glUniformMatrix4fv(program.viewMatrix, 1, GL_FALSE, viewMatrix.const_value_ptr()); Matrix4x4f projectionMatrix = Matrix4x4f::perspective(60.0f, WINDOW_WIDTH * 1.0f / WINDOW_HEIGHT, 1.0f, 100.0f); glUniformMatrix4fv(program.projectionMatrix, 1, GL_FALSE, projectionMatrix.const_value_ptr()); pSphereMesh->Render(); }
void renderScene() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(geometryPass.program); Matrix4x4f viewMatrix = camera.getMatrix(); glUniformMatrix4fv(geometryPass.viewMatrix, 1, GL_FALSE, viewMatrix.const_value_ptr()); Matrix4x4f projectionMatrix = Matrix4x4f::perspective(60.0f, WINDOW_WIDTH * 1.0f / WINDOW_HEIGHT, 1.0f, 100.0f); glUniformMatrix4fv(geometryPass.projectionMatrix, 1, GL_FALSE, projectionMatrix.const_value_ptr()); glUniform1i(geometryPass.textureSampler, 0); for (size_t i = 0; i < sizeof(boxPositions) / sizeof(boxPositions[0]); i++) { Matrix4x4f modelMatrix = Matrix4x4f::identity().translate(boxPositions[i]).rotatey(m_scale); glUniformMatrix4fv(geometryPass.modelMatrix, 1, GL_FALSE, modelMatrix.const_value_ptr()); pBoxMesh->Render(); } glUseProgram(0); }
int main() { init(); if (SDL_Init(SDL_INIT_VIDEO) < 0) { fprintf(stderr, "SDL_Init failed: %s\n", SDL_GetError()); return 1; } atexit(SDL_Quit); if (SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 32, SDL_OPENGL) == 0) { fprintf(stderr, "SDL_SetVideoMode failed: %s\n", SDL_GetError()); return 1; } cam_to_clip = perspective<float>(45.f / 180.f * 3.14159265f, 1.f, 0.1f, 100.f); Vector3f eye = Vector3f(4.f, 1.f, 4.f); Vector3f center = Vector3f(0.f, 0.f, 0.f); Vector3f up = Vector3f(0.f, 1.f, 0.f); cam_to_view = look_at<float>(eye, center, up); load_camera(); int prev_ticks = SDL_GetTicks(); int last_ticks = prev_ticks; int frames = 0; while (1) { int dt = SDL_GetTicks() - prev_ticks; prev_ticks += dt; // Handle events. SDL_Event ev; while (SDL_PollEvent(&ev)) { switch (ev.type) { case SDL_KEYDOWN: switch (ev.key.keysym.sym) { case SDLK_ESCAPE: return 0; case SDLK_1: fprintf(stderr, "rendering using OpenGL\n"); mode = RENDER_GL; last_ticks = SDL_GetTicks(); frames = 0; break; case SDLK_2: fprintf(stderr, "rendering using cpu ray tracing\n"); mode = RENDER_RT_CPU; last_ticks = SDL_GetTicks(); frames = 0; break; case SDLK_3: fprintf(stderr, "rendering using cuda ray tracing\n"); mode = RENDER_RT_CUDA; last_ticks = SDL_GetTicks(); frames = 0; break; case SDLK_u: { FILE* fp = fopen("camera.txt", "wt"); for (int i = 0; i < 16; i++) fprintf(fp, "%f ", cam_to_view.data()[i]); for (int i = 0; i < 16; i++) fprintf(fp, "%f ", cam_to_clip.data()[i]); fclose(fp); fprintf(stderr, "saved camera to camera.txt\n"); } break; case SDLK_p: load_camera(); break; default: break; } break; case SDL_MOUSEMOTION: if (ev.motion.state & 1) { float fdx = ev.motion.xrel / 400.; float fdy = ev.motion.yrel / 400.; cam_to_view = rotate(Vector3f(1.0f, 0.0, 0.0), fdy) * rotate(Vector3f(0.0, 1.0f, 0.0), fdx) * cam_to_view; } break; case SDL_QUIT: return 0; } } // Handle movement. float dtf = dt / 1000.f; Uint8* keys = SDL_GetKeyState(0); if (keys[SDLK_UP] || keys[SDLK_w]) move(Vector3f(0.f, 0.f, move_speed) * dtf); if (keys[SDLK_DOWN] || keys[SDLK_s]) move(Vector3f(0.f, 0.f, -move_speed) * dtf); if (keys[SDLK_LEFT] || keys[SDLK_a]) move(Vector3f(move_speed, 0.f, 0.f) * dtf); if (keys[SDLK_RIGHT] || keys[SDLK_d]) move(Vector3f(-move_speed, 0.f, 0.f) * dtf); // Draw things. switch (mode) { case RENDER_GL: draw_gl(); break; case RENDER_RT_CPU: draw_rt_cpu(); break; case RENDER_RT_CUDA: draw_rt_cuda(); break; }; SDL_GL_SwapBuffers(); // frames++; // fprintf(stderr, "average %.2f\n", (SDL_GetTicks() - last_ticks) / (double)frames); } return 0; }
void load(const char* fn) { FILE* fp = fopen(fn, "r"); for (;;) { Matrix4x4f m; int n = fscanf(fp, "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f", &m.data()[0], &m.data()[1], &m.data()[2], &m.data()[3], &m.data()[4], &m.data()[5], &m.data()[6], &m.data()[7], &m.data()[8], &m.data()[9], &m.data()[10], &m.data()[11], &m.data()[12], &m.data()[13], &m.data()[14], &m.data()[15]); if (n != 16) break; frames.push_back(m); } fclose(fp); }
void ISprite::Update(f32 delta) { //IBasicMesh::Update(delta); if (bPlaying && bAnimation) { fFrameTime += delta; if (fFrameTime > fCurrentFrameRate) { fFrameTime -= fCurrentFrameRate; if (iCurrentFrame + 1 == iFrames) { if (bLoop) { iCurrentFrame = 0; } else { bChanged = FALSE; } } else iCurrentFrame++; u32 oldId = pFrame->iFileId; pFrame = &pAnimationFrames[iCurrentFrame]; if (oldId != pFrame->iFileId) { sRelease(pFrameImage); pFrameImage = static_cast<ITexture *>(pRes->Get(_F(pFrame->iFileId), Seed::ObjectTexture, pPool)); } this->ReconfigureFrame(); } } if (!bChanged && !this->IsChanged()) return; uPixel p = iColor; p.rgba.r = iColor.argb.r; p.rgba.g = iColor.argb.g; p.rgba.b = iColor.argb.b; p.rgba.a = iColor.argb.a; if (!arCustomVertexData) { arCurrentVertexData = &vert[0]; vert[0].cVertex = Vector3f(-fAspectHalfWidth, -fAspectHalfHeight, (f32)iPriority); vert[0].iColor = p; vert[0].cCoords = Point2f(fTexS0, fTexT0); vert[1].cVertex = Vector3f(+fAspectHalfWidth, -fAspectHalfHeight, (f32)iPriority); vert[1].iColor = p; vert[1].cCoords = Point2f(fTexS1, fTexT0); vert[2].cVertex = Vector3f(-fAspectHalfWidth, +fAspectHalfHeight, (f32)iPriority); vert[2].iColor = p; vert[2].cCoords = Point2f(fTexS0, fTexT1); vert[3].cVertex = Vector3f(+fAspectHalfWidth, +fAspectHalfHeight, (f32)iPriority); vert[3].iColor = p; vert[3].cCoords = Point2f(fTexS1, fTexT1); } else { arCurrentVertexData = arCustomVertexData; } f32 ratio = pScreen->GetAspectRatio(); f32 x = fAspectHalfWidth + ISprite::GetX(); f32 y = fAspectHalfHeight + ISprite::GetY() * ratio; f32 lx = ISprite::GetLocalX(); f32 ly = ISprite::GetLocalY() * ratio; Matrix4x4f t1, t2, r, s; t1 = TranslationMatrix(lx + x, ly + y, 0.0f); r = RotationMatrix(AxisZ, DegToRad(ISprite::GetRotation())); s = ScaleMatrix(ISprite::GetScaleX(), ISprite::GetScaleY(), 1.0f); t2 = TranslationMatrix(-lx, -ly, 0.0f); Matrix4x4f transform = ((t1 * r) * s) * t2; if (bTransformationChanged || !arCustomVertexData) { for (u32 i = 0; i < iNumVertices; i++) { transform.Transform(arCurrentVertexData[i].cVertex); } } bChanged = FALSE; bTransformationChanged = FALSE; }
Matrix4x4f Matrix4x4f::identityMatrix() { Matrix4x4f identity; identity.setIdentity(); return identity; }
std::vector<Vec3f> BoneBridgeCAL3D::ComputeBoundingBoxCorners(const CalBoundingBox& box) const { std::vector<Vec3f> corners; // what we have is a set of 6 planes, stored as plane equation variables // what we need is 8 points for drawing a box // each point is the intersection of three of the planes // what we need to do is choose each set of 3 planes that intersects at a viable corner // begin at the beginning corners.clear(); // iterate through all combinations of distinct planes a, b, c for (int a = 0; a < 6-2; ++a) { for (int b = a+1; b < 6-1; ++b) { // if a and b are parallel, skip if (PlanesParallel(box.plane[a], box.plane[b])) { continue; } for (int c = b+1; c < 6-0; ++c) { // the three planes indexed a, b, c potentially intersect at a viable corner // if any two are parallel, we should skip this trio // getting this far, we know a and b are not parallel -- let's check a,c and b,c if (PlanesParallel(box.plane[a], box.plane[c]) || PlanesParallel(box.plane[b], box.plane[c])) { continue; } // we have three orthogonal planes, they should intersect at a single point, serving as a corner to the box const Matrix4x4f M( box.plane[a].a, box.plane[a].b, box.plane[a].c, 0, box.plane[b].a, box.plane[b].b, box.plane[b].c, 0, box.plane[c].a, box.plane[c].b, box.plane[c].c, 0, 0, 0, 0, 1); const Matrix4x4f Mi = M.Inverse(); { const Vec4f offsets( box.plane[a].d, box.plane[b].d, box.plane[c].d, 0.0f); const Vec4f corner = Mi * offsets; const Vec3f fixedCorner(corner[X], corner[Y], -corner[Z]); corners.push_back(fixedCorner); } } } } // make sure we're all good assert(corners.size() == 8); return corners; }
int CudaBVH::convert(BVHRT::Node* node, int idx) { assert(node); assert(idx < (int)nodes.size()); int ret = idx + 1; if (node->left) { // Negative index means leaf. nodes[idx].left_idx = node->left->is_leaf() ? -ret : ret; ret = convert(node->left, ret); nodes[idx].right_idx = node->right->is_leaf() ? -ret : ret; ret = convert(node->right, ret); aabbs_x[idx].x = node->left->aabb.min.x; aabbs_x[idx].y = node->left->aabb.max.x; aabbs_x[idx].z = node->right->aabb.min.x; aabbs_x[idx].w = node->right->aabb.max.x; aabbs_y[idx].x = node->left->aabb.min.y; aabbs_y[idx].y = node->left->aabb.max.y; aabbs_y[idx].z = node->right->aabb.min.y; aabbs_y[idx].w = node->right->aabb.max.y; aabbs_z[idx].x = node->left->aabb.min.z; aabbs_z[idx].y = node->left->aabb.max.z; aabbs_z[idx].z = node->right->aabb.min.z; aabbs_z[idx].w = node->right->aabb.max.z; } else { int n = (int)node->primitives.size(); nodes[idx].left_idx = (int)vertices.size(); nodes[idx].right_idx = (int)node->primitives.size() * 3; for (int i = 0; i < n; i++) { const Primitive& prim = bvh->get_primitive(node->primitives[i]); vertices.push_back(Vector4f(prim.v0, 1.f)); vertices.push_back(Vector4f(prim.v1, 1.f)); vertices.push_back(Vector4f(prim.v2, 1.f)); #if 0 Matrix4x4f m; m.set_column(0, Vector4f(prim.v0 - prim.v2, 0.f)); m.set_column(1, Vector4f(prim.v1 - prim.v2, 0.f)); m.set_column(2, Vector4f(cross(prim.v0 - prim.v2, prim.v1 - prim.v2) - prim.v2, 0.f)); m.set_column(3, Vector4f(prim.v2, 0.f)); m = invert(m); Vec4x3 v; v.v[0] = Vector4f(m.get(2, 0), m.get(2, 1), m.get(2, 2), -m.get(2, 3)); v.v[1] = Vector4f(m.get(0, 0), m.get(0, 1), m.get(0, 2), m.get(0, 3)); v.v[2] = Vector4f(m.get(1, 0), m.get(1, 1), m.get(1, 2), m.get(1, 3)); woop_tris.push_back(v); #endif } } return ret; }