void doRender(Renderer::RenderContext& renderContext) { const Model::BrushFace* face = m_helper.face(); const Mat4x4 fromFace = face->fromTexCoordSystemMatrix(Vec2f::Null, Vec2f::One, true); const Plane3& boundary = face->boundary(); const Mat4x4 toPlane = planeProjectionMatrix(boundary.distance, boundary.normal); const Mat4x4 fromPlane = invertedMatrix(toPlane); const Vec2f originPosition(toPlane * fromFace * Vec3(m_helper.originInFaceCoords())); const Vec2f faceCenterPosition(toPlane * m_helper.face()->boundsCenter()); const Color& handleColor = pref(Preferences::HandleColor); const Color& highlightColor = pref(Preferences::SelectedHandleColor); Renderer::ActiveShader shader(renderContext.shaderManager(), Renderer::Shaders::VaryingPUniformCShader); const Renderer::MultiplyModelMatrix toWorldTransform(renderContext.transformation(), fromPlane); { const Mat4x4 translation = translationMatrix(Vec3(originPosition)); const Renderer::MultiplyModelMatrix centerTransform(renderContext.transformation(), translation); if (m_highlight) shader.set("Color", highlightColor); else shader.set("Color", handleColor); m_outer.render(); } { const Mat4x4 translation = translationMatrix(Vec3(faceCenterPosition)); const Renderer::MultiplyModelMatrix centerTransform(renderContext.transformation(), translation); shader.set("Color", highlightColor); m_center.render(); } }
const m4x4f NAMESPACE::Trackball::matrix() const { if (m_Walkthrough) { return (m_Rotation.toMatrix()*translationMatrix(-m_Translation)); } else { return ( translationMatrix(m_Translation) * translationMatrix(m_Center) * m_Rotation.toMatrix() * translationMatrix(-m_Center) ); } }
void ScreenSpaceFramebuffer::render(){ glm::vec2 resolution = OsEng.windowWrapper().currentWindowResolution(); glm::vec4 size = _size.value(); float xratio = _originalViewportSize.x / (size.z-size.x); float yratio = _originalViewportSize.y / (size.w-size.y);; if(!_renderFunctions.empty()){ glViewport (-size.x*xratio, -size.y*yratio, _originalViewportSize.x*xratio, _originalViewportSize.y*yratio); GLint defaultFBO = _framebuffer->getActiveObject(); _framebuffer->activate(); glClearColor (0.0f, 0.0f, 0.0f, 0.0f); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_ALPHA_TEST); for(auto renderFunction : _renderFunctions){ (*renderFunction)(); } _framebuffer->deactivate(); glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); glViewport (0, 0, resolution.x, resolution.y); glm::mat4 rotation = rotationMatrix(); glm::mat4 translation = translationMatrix(); glm::mat4 scale = scaleMatrix(); scale = glm::scale(scale, glm::vec3((1.0/xratio), -(1.0/yratio), 1.0f)); glm::mat4 modelTransform = rotation*translation*scale; draw(modelTransform); } }
Mesh::Mesh(const std::vector<Point3D>& verts, const std::vector<std::vector<int>>& faces) : m_verts(verts), m_faces(faces) { Point3D smallPoint(m_verts[0][0], m_verts[0][1], m_verts[0][2]); Point3D largePoint(m_verts[0][0], m_verts[0][1], m_verts[0][2]); // Get the minimum and maximum coordinates for (const auto& vert : m_verts) { for (auto i = 0; i < 3; ++i) { largePoint[i] = std::max(largePoint[i], vert[i]); smallPoint[i] = std::min(smallPoint[i], vert[i]); } } lowerBound = smallPoint; boundsRange = largePoint - smallPoint; // Enforce a minimum size (e.g. for planes) double MIN_SIZE = 0.2; for (auto i = 0; i < 3; ++i) { boundsRange[i] = std::max(boundsRange[i], MIN_SIZE); } // Translate to put lower corner at origin Matrix4x4 xlate = translationMatrix( -lowerBound[0], -lowerBound[1], -lowerBound[2]); // And scale down to get unit cube Matrix4x4 scale = scaleMatrix( 1/boundsRange[0], 1/boundsRange[1], 1/boundsRange[2]); boundingCubeInverse = scale * xlate;//xlate * scale; }
//! [2] void BasicOperations::paintEvent(QPaintEvent *) { double pi = 3.14; double a = pi/180 * 45.0; double sina = sin(a); double cosa = cos(a); QMatrix translationMatrix(1, 0, 0, 1, 50.0, 50.0); QMatrix rotationMatrix(cosa, sina, -sina, cosa, 0, 0); QMatrix scalingMatrix(0.5, 0, 0, 1.0, 0, 0); QMatrix matrix; matrix = scalingMatrix * rotationMatrix * translationMatrix; QPainter painter(this); painter.setPen(QPen(Qt::blue, 1, Qt::DashLine)); painter.drawRect(0, 0, 100, 100); painter.setMatrix(matrix); painter.setFont(QFont("Helvetica", 24)); painter.setPen(QPen(Qt::black, 1)); painter.drawText(20, 10, "QMatrix"); }
void Brush::moveBoundary(Face& face, const Vec3f& delta, bool lockTexture) { assert(canMoveBoundary(face, delta)); const Mat4f pointTransform = translationMatrix(delta); face.transform(pointTransform, Mat4f::Identity, false, false); rebuildGeometry(); }
void CTouchFreeCamera::Update(float dt) { if(m_isDragging) { float deltaX = m_dragPosition.x - m_mousePosition.x; float deltaY = m_dragPosition.y - m_mousePosition.y; m_cameraHAngle = m_dragHAngle + deltaX * 0.015f; m_cameraVAngle = m_dragVAngle + deltaY * 0.015f; m_cameraVAngle = std::min<float>(m_cameraVAngle, M_PI / 2); m_cameraVAngle = std::max<float>(m_cameraVAngle, -M_PI / 2); } CMatrix4 yawMatrix(CMatrix4::MakeAxisYRotation(m_cameraHAngle)); CMatrix4 pitchMatrix(CMatrix4::MakeAxisXRotation(m_cameraVAngle)); CMatrix4 rotationMatrix = yawMatrix * pitchMatrix; if(m_isStrafingLeft || m_isStrafingRight) { CVector3 rightVector = CVector3(1, 0, 0) * rotationMatrix; float direction = m_isStrafingLeft ? (-1.0f) : (1.0f); m_cameraPosition += (rightVector * direction * MOVE_SPEED * dt); } if(m_isMovingForward || m_isMovingBackward) { CVector3 forwardVector = CVector3(0, 0, 1) * rotationMatrix; float direction = m_isMovingForward ? (-1.0f) : (1.0f); m_cameraPosition += (forwardVector * direction * MOVE_SPEED * dt); } CMatrix4 translationMatrix(CMatrix4::MakeTranslation(-m_cameraPosition.x, -m_cameraPosition.y, -m_cameraPosition.z)); CMatrix4 totalMatrix = translationMatrix * rotationMatrix; SetViewMatrix(totalMatrix); }
void OverlayRenderer::render(RenderContext& context, const float viewWidth, const float viewHeight) { if (m_vbo == NULL) m_vbo = new Vbo(GL_ARRAY_BUFFER, 0xFFFF); if (m_compass == NULL) m_compass = new CompassRenderer(); glClear(GL_DEPTH_BUFFER_BIT); const Mat4f projection = orthoMatrix(0.0f, 1000.0f, -viewWidth / 2.0f, viewHeight / 2.0f, viewWidth / 2.0f, -viewHeight / 2.0f); const Mat4f view = viewMatrix(Vec3f::PosY, Vec3f::PosZ) * translationMatrix(500.0f * Vec3f::PosY); Renderer::ApplyTransformation ortho(context.transformation(), projection, view); const Mat4f compassTransformation = translationMatrix(Vec3f(-viewWidth / 2.0f + 50.0f, 0.0f, -viewHeight / 2.0f + 50.0f)) * scalingMatrix(2.0f); Renderer::ApplyModelMatrix applyCompassTranslate(context.transformation(), compassTransformation); m_compass->render(*m_vbo, context); }
void Compass::doRender(RenderContext& renderContext) { const Camera& camera = renderContext.camera(); const Camera::Viewport& viewport = camera.unzoomedViewport(); const int viewWidth = viewport.width; const int viewHeight = viewport.height; const Mat4x4f projection = orthoMatrix(0.0f, 1000.0f, -viewWidth / 2.0f, viewHeight / 2.0f, viewWidth / 2.0f, -viewHeight / 2.0f); const Mat4x4f view = viewMatrix(Vec3f::PosY, Vec3f::PosZ) * translationMatrix(500.0f * Vec3f::PosY); const ReplaceTransformation ortho(renderContext.transformation(), projection, view); const Mat4x4f compassTransformation = translationMatrix(Vec3f(-viewWidth / 2.0f + 55.0f, 0.0f, -viewHeight / 2.0f + 55.0f)) * scalingMatrix<4>(2.0f); const MultiplyModelMatrix compass(renderContext.transformation(), compassTransformation); const Mat4x4f cameraTransformation = cameraRotationMatrix(camera); glAssert(glClear(GL_DEPTH_BUFFER_BIT)); renderBackground(renderContext); glAssert(glClear(GL_DEPTH_BUFFER_BIT)); doRenderCompass(renderContext, cameraTransformation); }
V3R SymmetryOperation::getReducedVector(const Kernel::IntMatrix &matrix, const V3R &vector) const { Kernel::IntMatrix translationMatrix(3, 3, false); for (size_t i = 0; i < order(); ++i) { Kernel::IntMatrix tempMatrix(3, 3, true); for (size_t j = 0; j < i; ++j) { tempMatrix *= matrix; } translationMatrix += tempMatrix; } return (translationMatrix * vector) * RationalNumber(1, static_cast<int>(order())); }
void Renderable::setMatrix() { #ifdef OPENGL_ES1 glTranslatef(posx, posy, posz); glRotatef(rot, rotx, roty, rotz); glScalef(scalex, scaley, scalez); #else Mat16 tmp = translationMatrix(posx, posy, posz); currentModelViewMatrix = multiplyMatrix(currentModelViewMatrix, tmp); tmp = rotationMatrix(rot / 180 * M_PI, rotx, roty, rotz); currentModelViewMatrix = multiplyMatrix(currentModelViewMatrix, tmp); tmp = scaleMatrix(scalex, scaley, scalez); currentModelViewMatrix = multiplyMatrix(currentModelViewMatrix, tmp); glUniformMatrix4fv(shaderModelViewMatrix, 1, GL_FALSE, currentModelViewMatrix.m); glUniformMatrix3fv(shaderNormalMatrix, 1, GL_FALSE, transposedInverseMatrix9(currentModelViewMatrix).m); #endif }
GLC_Matrix4x4 GLC_PullManipulator::doManipulate(const GLC_Point3d& newPoint, const GLC_Vector3d& projectionDirection) { // Project the given point on the sliding plane with the given direction GLC_Point3d projectedPoint; GLC_Line3d projectionLine(newPoint, projectionDirection); glc::lineIntersectPlane(projectionLine, GLC_AbstractManipulator::m_SliddingPlane, &projectedPoint); // Project the point on the pulling direction projectedPoint= glc::project(projectedPoint, GLC_Line3d(GLC_AbstractManipulator::previousPosition(), m_PullDirection)); // Compute the translation matrix GLC_Matrix4x4 translationMatrix(projectedPoint - GLC_AbstractManipulator::m_PreviousPosition); // Update previous position to this position GLC_AbstractManipulator::m_PreviousPosition= projectedPoint; return translationMatrix; }
static void fpsCameraViewMatrix(GLFWwindow *window, float *view) { // initial camera config static float position[] = { 0.0f, 0.3f, 1.5f }; static float rotation[] = { 0.0f, 0.0f }; // mouse look static double lastMouse[] = { 0.0, 0.0 }; double mouse[2]; glfwGetCursorPos(window, &mouse[0], &mouse[1]); if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS) { rotation[0] += (float)(mouse[1] - lastMouse[1]) * -0.2f; rotation[1] += (float)(mouse[0] - lastMouse[0]) * -0.2f; } lastMouse[0] = mouse[0]; lastMouse[1] = mouse[1]; float rotationY[16], rotationX[16], rotationYX[16]; rotationMatrix(rotationX, rotation[0], 1.0f, 0.0f, 0.0f); rotationMatrix(rotationY, rotation[1], 0.0f, 1.0f, 0.0f); multiplyMatrices(rotationYX, rotationY, rotationX); // keyboard movement (WSADEQ) float speed = (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) ? 0.1f : 0.01f; float movement[3] = {0}; if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) movement[2] -= speed; if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) movement[2] += speed; if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) movement[0] -= speed; if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) movement[0] += speed; if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) movement[1] -= speed; if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) movement[1] += speed; float worldMovement[3]; transformPosition(worldMovement, rotationYX, movement); position[0] += worldMovement[0]; position[1] += worldMovement[1]; position[2] += worldMovement[2]; // construct view matrix float inverseRotation[16], inverseTranslation[16]; transposeMatrix(inverseRotation, rotationYX); translationMatrix(inverseTranslation, -position[0], -position[1], -position[2]); multiplyMatrices(view, inverseRotation, inverseTranslation); // = inverse(translation(position) * rotationYX); }
void RotateHandle::render(Model::RotateHandleHit* hit, Renderer::Vbo& vbo, Renderer::RenderContext& renderContext, float angle) { Preferences::PreferenceManager& prefs = Preferences::PreferenceManager::preferences(); const float distance = renderContext.camera().distanceTo(position()); const float factor = prefs.getFloat(Preferences::HandleScalingFactor) * distance; const Mat4f matrix = translationMatrix(position()) * scalingMatrix(factor); Renderer::ApplyModelMatrix applyTranslation(renderContext.transformation(), matrix); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); Renderer::SetVboState activateVbo(vbo, Renderer::Vbo::VboActive); if (hit != NULL) { renderAxis(hit, vbo, renderContext); renderRing(hit, vbo, renderContext, angle); } else { Vec3f xAxis, yAxis, zAxis; axes(renderContext.camera().position(), xAxis, yAxis, zAxis); Renderer::ActivateShader coloredShader(renderContext.shaderManager(), Renderer::Shaders::ColoredHandleShader); Renderer::AxisFigure axisFigure(m_axisLength); axisFigure.setAxes(true, true, true); axisFigure.setXColor(prefs.getColor(Preferences::XColor)); axisFigure.setYColor(prefs.getColor(Preferences::YColor)); axisFigure.setZColor(prefs.getColor(Preferences::ZColor)); axisFigure.render(vbo, renderContext); Renderer::ActivateShader shader(renderContext.shaderManager(), Renderer::Shaders::HandleShader); shader.setUniformVariable("Color", Color(1.0f, 1.0f, 1.0f, 0.25f)); Renderer::RingFigure(Axis::AX, yAxis, zAxis, m_ringRadius, m_ringThickness, 8).render(vbo, renderContext); Renderer::RingFigure(Axis::AY, xAxis, zAxis, m_ringRadius, m_ringThickness, 8).render(vbo, renderContext); Renderer::RingFigure(Axis::AZ, xAxis, yAxis, m_ringRadius, m_ringThickness, 8).render(vbo, renderContext); } glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); }
bool Brush::canMoveBoundary(const Face& face, const Vec3f& delta) const { const Mat4f pointTransform = translationMatrix(delta); BrushGeometry testGeometry(m_worldBounds); Face testFace(face); testFace.transform(pointTransform, Mat4f::Identity, false, false); FaceSet droppedFaces; FaceList::const_iterator it, end; for (it = m_faces.begin(), end = m_faces.end(); it != end; ++it) { Face* otherFace = *it; if (otherFace != &face) testGeometry.addFace(*otherFace, droppedFaces); } BrushGeometry::CutResult result = testGeometry.addFace(testFace, droppedFaces); bool inWorldBounds = m_worldBounds.contains(testGeometry.bounds); m_geometry->restoreFaceSides(); return inWorldBounds && result == BrushGeometry::Split && droppedFaces.empty(); }
void EntityModelRenderer::render(ShaderProgram& shaderProgram, Transformation& transformation, const Vec3f& position, const Quatf& rotation) { const Mat4f matrix = translationMatrix(position) * rotationMatrix(rotation); ApplyModelMatrix applyMatrix(transformation, matrix); render(shaderProgram); }
std::set<const Model*> UniformGrid::getModels(const Ray& ray) const { std::set<const Model*> models; Point3D nextT(0, 0, 0); // The point *within* the grid where the ray first intersected it Point3D rayStartPoint(0, 0, 0); if (!inGrid(ray.start)) { const auto& sp = startPoint; // Not in the grid: We will use a cube the sz of whole grid to find // the point of entry into the grid auto gridCubeInverse = (translationMatrix(sp[0], sp[0], sp[0]) * gridSizeScaleMatrix).invert(); HitRecord hr; if (!utilityCube.intersects(ray, &hr, gridCubeInverse)) { // Does not intersect the grid even return models; } nextT[0] = hr.t; nextT[1] = hr.t; nextT[2] = hr.t; rayStartPoint = ray.at(hr.t); } else { rayStartPoint = ray.start; } // Place in the grid we are currently stepping through CellCoord gridCoord = coordAt(rayStartPoint); Vector3D dir( std::abs(ray.dir[0]), std::abs(ray.dir[1]), std::abs(ray.dir[2])); // These values are in units of t: how far we must go to travel a whole cell Vector3D dt( isZero(dir[0]) ? 0 : cellSize / dir[0], isZero(dir[1]) ? 0 : cellSize / dir[1], isZero(dir[2]) ? 0 : cellSize / dir[2] ); { // The bottom left corner of the cell we are starting in Point3D gsp = pointAt(gridCoord); // "Grid start point" // Determine how far, in units of t, we have to go in any direction // to reach the next cell // If we are going "forwards" in a coordinate then we need to travel to // gsp + cellSize. If we are going "backwards" in a coordinate then we need // to travel to only gsp. for (int i = 0; i < 3; ++i) { if (isZero(dir[i])) { nextT[i] = -1; continue; } if (ray.dir[i] < 0) { nextT[i] += (rayStartPoint[i] - gsp[i]) / dir[i]; } else { nextT[i] += (gsp[i] + cellSize - rayStartPoint[i]) / dir[i]; } } } // Which direction in the grid to move when we hit a "next" value CellCoord incs( (ray.dir[0] > 0) ? 1 : -1, (ray.dir[1] > 0) ? 1 : -1, (ray.dir[2] > 0) ? 1 : -1 ); // Check if a coord is still valid auto coordOk = [&] (int coord) -> bool { return 0 <= coord && coord < sideLength; }; auto smaller = [] (double a, double b) -> bool { return (b < 0) || a <= b; }; while (coordOk(gridCoord.x) && coordOk(gridCoord.y) && coordOk(gridCoord.z)) { for (const Model* model : cells[indexFor(gridCoord)].models) { models.insert(model); } for (int i = 0; i < 3; ++i) { if (nextT[i] < 0) continue; const auto a = nextT[(i + 1) % 3]; const auto b = nextT[(i + 2) % 3]; if (smaller(nextT[i], a) && smaller(nextT[i], b)) { nextT[i] += dt[i]; gridCoord[i] += incs[i]; break; } } } return models; }
bool UniformGrid::intersectsCell(const Model& model, const CellCoord& coord) { // Left side // Bottom left point Point3D p0 = pointAt(coord); Point3D p1(p0[0], p0[1] + cellSize, p0[2]); Point3D p2(p0[0], p0[1] + cellSize, p0[2] + cellSize); Point3D p3(p0[0], p0[1], p0[2] + cellSize); // Right side Point3D p4(p0[0] + cellSize, p0[1], p0[2]); Point3D p5(p0[0] + cellSize, p0[1] + cellSize, p0[2]); Point3D p6(p0[0] + cellSize, p0[1] + cellSize, p0[2] + cellSize); Point3D p7(p0[0] + cellSize, p0[1], p0[2] + cellSize); const std::vector<Point3D> pts = {p0, p1, p2, p3, p4, p5, p6, p7}; auto cellMat = translationMatrix(p0[0], p0[1], p0[2]) * cellSizeScaleMatrix; // But we need the inverse of course cellMat = cellMat.invert(); // Check if a pt is in the cell auto inCell = [&] (const Point3D& pt) -> bool { return p0[0] <= pt[0] && pt[0] <= (p0[0] + cellSize) && p0[1] <= pt[1] && pt[1] <= (p0[1] + cellSize) && p0[2] <= pt[2] && pt[2] <= (p0[2] + cellSize); }; // First, we need to get the 8 points of the bounding box auto bbox = model.getBoundingBox(); auto inBoundingBox = [&bbox] (const Point3D& pt) -> bool { // We are in the box if we are in between all the opposite parallel planes const auto c1 = bbox[0]; // Bottom back left corner const auto v1a = bbox[1] - c1; // Bottom back left to bottom back right const auto v1b = bbox[3] - c1; // Bottom back left to top back left const auto v1c = bbox[4] - c1; // Bottom back left to bottom front left const auto n1 = v1a.cross(v1b); // Back face const auto n2 = v1b.cross(v1c); // Left face const auto n3 = v1c.cross(v1a); // Bottom face const auto c2 = bbox[6]; // Top front right corner const auto v2a = bbox[5] - c2; // Top front right to bottom front right const auto v2b = bbox[7] - c2; // Top front right to top front left const auto v2c = bbox[2] - c2; // Top front right to top back right // We want this to be opposite sign (i.e. not pointing inwards) // so we do the opposite cross as above const auto n4 = v2b.cross(v2a); // Front face const auto n5 = v2c.cross(v2b); // Top face const auto n6 = v2a.cross(v2c); // Right face return betweenPlanes(n1, c1, n4, c2, pt) && betweenPlanes(n2, c1, n6, c2, pt) && betweenPlanes(n3, c1, n5, c2, pt); }; // A corner of the bbox being inside the cell implies an intersection // between the bbox and the cell. for (const auto& pt : bbox) { if (inCell(pt)) { return true; } } // Similarly, a corner of cell inside bbox implies intersection for (const auto& pt : pts) { if (inBoundingBox(pt)) { return true; } } // Check if any of the 12 lines from bbox intersect this cell HitRecord hr; for (size_t i = 0; i < 8; ++i) { // This is the vector of one edge Vector3D v = bbox[(i % 4 == 0) ? i + 3 : i - 1] - bbox[i]; Ray ray(bbox[i] - v, bbox[i]); if (utilityCube.intersects(ray, &hr, cellMat) && 1 <= hr.t && hr.t <= 2) { // This edge of the bounding box intersects our cell cube. return true; } } for (size_t i = 0; i < 4; ++i) { Vector3D v = bbox[i + 4] - bbox[i]; Ray ray(bbox[i] - v, bbox[i]); if (utilityCube.intersects(ray, &hr, cellMat) && 1 <= hr.t && hr.t <= 2) { // This edge of the bounding box intersects our cell cube. return true; } } // Now check if any of the 12 lines from this cell intersect the model for (size_t i = 0; i < pts.size(); ++i) { Vector3D v = pts[(i % 4 == 0) ? i + 3 : i - 1] - pts[i]; // Note: We are doing pts[i] - v and checking for t between 1 and 2. // This is equivalent to checking between 0 and 1 without doing the // subtraction, *but* we have an epsilon check in the intersects code. // For this case, we do *not* want to bother with epsilon check, so we // will check from 1 to 2 to avoid it. if (model.intersects(Ray(pts[i] - v, pts[i]), &hr)) { if (1 <= hr.t && hr.t <= 2) { return true; } } } // Now we have to check the struts between the two sides for (size_t i = 0; i < 4; ++i) { Vector3D v = pts[i + 4] - pts[i]; if (model.intersects(Ray(pts[i] - v, pts[i]), &hr)) { if (1 <= hr.t && hr.t <= 2) { return true; } } } return false; }
void ScreenSpaceImage::render() { draw(rotationMatrix() * translationMatrix() * scaleMatrix()); }
/*! \param x Value of x translation \param y Value of y translation \param z Value of z translation */ Matrix4& translate(T const & x, T const & y, T const & z=0) { Matrix4 tmp = translationMatrix(x, y, z); tmp *= *this; *this = tmp; return (*this); }
void SceneNode::translate(const Vector3D& amount) { Matrix4x4 t = translationMatrix(amount); m_trans = m_trans * t; m_invtrans = t.invert() * m_invtrans; }
void AtmosphereSample::Update(double CurrTime, double ElapsedTime) { SampleBase::Update(CurrTime, ElapsedTime); m_fElapsedTime = static_cast<float>(ElapsedTime); const auto& SCDesc = m_pSwapChain->GetDesc(); // Set world/view/proj matrices and global shader constants float aspectRatio = (float)SCDesc.Width / SCDesc.Height; float3 CamZ = normalize( m_f3CameraDir ); float3 CamX = normalize( cross( float3( 0, 1, 0 ), CamZ ) ); float3 CamY = normalize( cross( CamZ, CamX ) ); m_mCameraView = translationMatrix( -m_f3CameraPos ) * ViewMatrixFromBasis( CamX, CamY, CamZ ); // This projection matrix is only used to set up directions in view frustum // Actual near and far planes are ignored float FOV = (float)M_PI/4.f; float4x4 mTmpProj = Projection(FOV, aspectRatio, 50.f, 500000.f, m_bIsDXDevice); float fEarthRadius = AirScatteringAttribs().fEarthRadius; float3 EarthCenter(0, -fEarthRadius, 0); float fNearPlaneZ, fFarPlaneZ; ComputeApproximateNearFarPlaneDist(m_f3CameraPos, m_mCameraView, mTmpProj, EarthCenter, fEarthRadius, fEarthRadius + m_fMinElevation, fEarthRadius + m_fMaxElevation, fNearPlaneZ, fFarPlaneZ); fNearPlaneZ = std::max(fNearPlaneZ, 50.f); fFarPlaneZ = std::max(fFarPlaneZ, fNearPlaneZ+100.f); fFarPlaneZ = std::max(fFarPlaneZ, 1000.f); m_mCameraProj = Projection(FOV, aspectRatio, fNearPlaneZ, fFarPlaneZ, m_bIsDXDevice); #if 0 if( m_bAnimateSun ) { auto &LightOrientationMatrix = *m_pDirLightOrienationCamera->GetParentMatrix(); float3 RotationAxis( 0.5f, 0.3f, 0.0f ); float3 LightDir = m_pDirLightOrienationCamera->GetLook() * -1; float fRotationScaler = ( LightDir.y > +0.2f ) ? 50.f : 1.f; float4x4 RotationMatrix = float4x4RotationAxis(RotationAxis, 0.02f * (float)deltaSeconds * fRotationScaler); LightOrientationMatrix = LightOrientationMatrix * RotationMatrix; m_pDirLightOrienationCamera->SetParentMatrix(LightOrientationMatrix); } float dt = (float)ElapsedTime; if (m_Animate && dt > 0 && dt < 0.2f) { float3 axis; float angle = 0; AxisAngleFromRotation(axis, angle, m_SpongeRotation); if (length(axis) < 1.0e-6f) axis[1] = 1; angle += m_AnimationSpeed * dt; if (angle >= 2.0f*FLOAT_PI) angle -= 2.0f*FLOAT_PI; else if (angle <= 0) angle += 2.0f*FLOAT_PI; m_SpongeRotation = RotationFromAxisAngle(axis, angle); } #endif UpdateGUI(); }
void AtmosphereSample::RenderShadowMap(IDeviceContext *pContext, LightAttribs &LightAttribs, const float4x4 &mCameraView, const float4x4 &mCameraProj ) { ShadowMapAttribs& ShadowMapAttribs = LightAttribs.ShadowAttribs; float3 v3DirOnLight = (float3&)LightAttribs.f4DirOnLight; float3 v3LightDirection = -v3DirOnLight; // Declare working vectors float3 vLightSpaceX, vLightSpaceY, vLightSpaceZ; // Compute an inverse vector for the direction on the sun vLightSpaceZ = v3LightDirection; // And a vector for X light space vLightSpaceX = float3( 1.0f, 0.0, 0.0 ); // Compute the cross products vLightSpaceY = cross(vLightSpaceX, vLightSpaceZ); vLightSpaceX = cross(vLightSpaceZ, vLightSpaceY); // And then normalize them vLightSpaceX = normalize( vLightSpaceX ); vLightSpaceY = normalize( vLightSpaceY ); vLightSpaceZ = normalize( vLightSpaceZ ); // Declare a world to light space transformation matrix // Initialize to an identity matrix float4x4 WorldToLightViewSpaceMatr = ViewMatrixFromBasis( vLightSpaceX, vLightSpaceY, vLightSpaceZ ); ShadowMapAttribs.mWorldToLightViewT = transposeMatrix( WorldToLightViewSpaceMatr ); float3 f3CameraPosInLightSpace = m_f3CameraPos * WorldToLightViewSpaceMatr; float fMainCamNearPlane, fMainCamFarPlane; GetNearFarPlaneFromProjMatrix( mCameraProj, fMainCamNearPlane, fMainCamFarPlane, m_bIsDXDevice); for(int i=0; i < MAX_CASCADES; ++i) ShadowMapAttribs.fCascadeCamSpaceZEnd[i] = +FLT_MAX; // Render cascades for(int iCascade = 0; iCascade < m_TerrainRenderParams.m_iNumShadowCascades; ++iCascade) { auto &CurrCascade = ShadowMapAttribs.Cascades[iCascade]; float4x4 CascadeFrustumProjMatrix; float &fCascadeFarZ = ShadowMapAttribs.fCascadeCamSpaceZEnd[iCascade]; float fCascadeNearZ = (iCascade == 0) ? fMainCamNearPlane : ShadowMapAttribs.fCascadeCamSpaceZEnd[iCascade-1]; fCascadeFarZ = fMainCamFarPlane; if (iCascade < m_TerrainRenderParams.m_iNumShadowCascades-1) { float ratio = fMainCamFarPlane / fMainCamNearPlane; float power = (float)(iCascade+1) / (float)m_TerrainRenderParams.m_iNumShadowCascades; float logZ = fMainCamNearPlane * pow(ratio, power); float range = fMainCamFarPlane - fMainCamNearPlane; float uniformZ = fMainCamNearPlane + range * power; fCascadeFarZ = m_fCascadePartitioningFactor * (logZ - uniformZ) + uniformZ; } float fMaxLightShaftsDist = 3e+5f; // Ray marching always starts at the camera position, not at the near plane. // So we must make sure that the first cascade used for ray marching covers the camera position CurrCascade.f4StartEndZ.x = (iCascade == m_PPAttribs.m_iFirstCascade) ? 0 : std::min(fCascadeNearZ, fMaxLightShaftsDist); CurrCascade.f4StartEndZ.y = std::min(fCascadeFarZ, fMaxLightShaftsDist); CascadeFrustumProjMatrix = mCameraProj; SetNearFarClipPlanes( CascadeFrustumProjMatrix, fCascadeNearZ, fCascadeFarZ, m_bIsDXDevice ); float4x4 CascadeFrustumViewProjMatr = mCameraView * CascadeFrustumProjMatrix; float4x4 CascadeFrustumProjSpaceToWorldSpace = inverseMatrix(CascadeFrustumViewProjMatr); float4x4 CascadeFrustumProjSpaceToLightSpace = CascadeFrustumProjSpaceToWorldSpace * WorldToLightViewSpaceMatr; // Set reference minimums and maximums for each coordinate float3 f3MinXYZ(f3CameraPosInLightSpace), f3MaxXYZ(f3CameraPosInLightSpace); // First cascade used for ray marching must contain camera within it if( iCascade != m_PPAttribs.m_iFirstCascade ) { f3MinXYZ = float3(+FLT_MAX, +FLT_MAX, +FLT_MAX); f3MaxXYZ = float3(-FLT_MAX, -FLT_MAX, -FLT_MAX); } for(int iClipPlaneCorner=0; iClipPlaneCorner < 8; ++iClipPlaneCorner) { float3 f3PlaneCornerProjSpace( (iClipPlaneCorner & 0x01) ? +1.f : - 1.f, (iClipPlaneCorner & 0x02) ? +1.f : - 1.f, // Since we use complimentary depth buffering, // far plane has depth 0 (iClipPlaneCorner & 0x04) ? 1.f : (m_bIsDXDevice ? 0.f : -1.f)); float3 f3PlaneCornerLightSpace = f3PlaneCornerProjSpace * CascadeFrustumProjSpaceToLightSpace; f3MinXYZ = min(f3MinXYZ, f3PlaneCornerLightSpace); f3MaxXYZ = max(f3MaxXYZ, f3PlaneCornerLightSpace); } // It is necessary to ensure that shadow-casting patches, which are not visible // in the frustum, are still rendered into the shadow map f3MinXYZ.z -= AirScatteringAttribs().fEarthRadius * sqrt(2.f); // Align cascade extent to the closest power of two float fShadowMapDim = (float)m_uiShadowMapResolution; float fCascadeXExt = (f3MaxXYZ.x - f3MinXYZ.x) * (1 + 1.f/fShadowMapDim); float fCascadeYExt = (f3MaxXYZ.y - f3MinXYZ.y) * (1 + 1.f/fShadowMapDim); const float fExtStep = 2.f; fCascadeXExt = pow( fExtStep, ceil( log(fCascadeXExt)/log(fExtStep) ) ); fCascadeYExt = pow( fExtStep, ceil( log(fCascadeYExt)/log(fExtStep) ) ); // Align cascade center with the shadow map texels to alleviate temporal aliasing float fCascadeXCenter = (f3MaxXYZ.x + f3MinXYZ.x)/2.f; float fCascadeYCenter = (f3MaxXYZ.y + f3MinXYZ.y)/2.f; float fTexelXSize = fCascadeXExt / fShadowMapDim; float fTexelYSize = fCascadeXExt / fShadowMapDim; fCascadeXCenter = floor(fCascadeXCenter/fTexelXSize) * fTexelXSize; fCascadeYCenter = floor(fCascadeYCenter/fTexelYSize) * fTexelYSize; // Compute new cascade min/max xy coords f3MaxXYZ.x = fCascadeXCenter + fCascadeXExt/2.f; f3MinXYZ.x = fCascadeXCenter - fCascadeXExt/2.f; f3MaxXYZ.y = fCascadeYCenter + fCascadeYExt/2.f; f3MinXYZ.y = fCascadeYCenter - fCascadeYExt/2.f; CurrCascade.f4LightSpaceScale.x = 2.f / (f3MaxXYZ.x - f3MinXYZ.x); CurrCascade.f4LightSpaceScale.y = 2.f / (f3MaxXYZ.y - f3MinXYZ.y); CurrCascade.f4LightSpaceScale.z = (m_bIsDXDevice ? 1.f : 2.f) / (f3MaxXYZ.z - f3MinXYZ.z); // Apply bias to shift the extent to [-1,1]x[-1,1]x[0,1] for DX or to [-1,1]x[-1,1]x[-1,1] for GL // Find bias such that f3MinXYZ -> (-1,-1,0) for DX or (-1,-1,-1) for GL CurrCascade.f4LightSpaceScaledBias.x = -f3MinXYZ.x * CurrCascade.f4LightSpaceScale.x - 1.f; CurrCascade.f4LightSpaceScaledBias.y = -f3MinXYZ.y * CurrCascade.f4LightSpaceScale.y - 1.f; CurrCascade.f4LightSpaceScaledBias.z = -f3MinXYZ.z * CurrCascade.f4LightSpaceScale.z + (m_bIsDXDevice ? 0.f : -1.f); float4x4 ScaleMatrix = scaleMatrix( CurrCascade.f4LightSpaceScale.x, CurrCascade.f4LightSpaceScale.y, CurrCascade.f4LightSpaceScale.z ); float4x4 ScaledBiasMatrix = translationMatrix( CurrCascade.f4LightSpaceScaledBias.x, CurrCascade.f4LightSpaceScaledBias.y, CurrCascade.f4LightSpaceScaledBias.z ) ; // Note: bias is applied after scaling! float4x4 CascadeProjMatr = ScaleMatrix * ScaledBiasMatrix; //D3DXMatrixOrthoOffCenterLH( &m_LightOrthoMatrix, MinX, MaxX, MinY, MaxY, MaxZ, MinZ); // Adjust the world to light space transformation matrix float4x4 WorldToLightProjSpaceMatr = WorldToLightViewSpaceMatr * CascadeProjMatr; float4x4 ProjToUVScale, ProjToUVBias; if( m_bIsDXDevice ) { ProjToUVScale = scaleMatrix( 0.5f, -0.5f, 1.f ); ProjToUVBias = translationMatrix( 0.5f, 0.5f, 0.f ); } else { ProjToUVScale = scaleMatrix( 0.5f, 0.5f, 0.5f ); ProjToUVBias = translationMatrix( 0.5f, 0.5f, 0.5f ); } float4x4 WorldToShadowMapUVDepthMatr = WorldToLightProjSpaceMatr * ProjToUVScale * ProjToUVBias; ShadowMapAttribs.mWorldToShadowMapUVDepthT[iCascade] = transposeMatrix( WorldToShadowMapUVDepthMatr ); m_pImmediateContext->SetRenderTargets( 0, nullptr, m_pShadowMapDSVs[iCascade] ); m_pImmediateContext->ClearDepthStencil( m_pShadowMapDSVs[iCascade], CLEAR_DEPTH_FLAG, 1.f ); // Render terrain to shadow map { MapHelper<CameraAttribs> CamAttribs( m_pImmediateContext, m_pcbCameraAttribs, MAP_WRITE, MAP_FLAG_DISCARD ); CamAttribs->mViewProjT = transposeMatrix( WorldToLightProjSpaceMatr ); } m_EarthHemisphere.Render(m_pImmediateContext, m_TerrainRenderParams, m_f3CameraPos, WorldToLightProjSpaceMatr, nullptr, nullptr, nullptr, true); } pContext->SetRenderTargets( 0, nullptr, nullptr ); }
void App::update(float delta_time) { if (anim_play) frame_count++; if (!hide_gui) gui(); // autoreload frag shader (every 60 frames) if (shader_filepath && shader_file_autoreload && (frame_count % 60) == 0) { struct stat attr; if (!stat(shader_filepath, &attr)) { // file exists if (attr.st_mtime > shader_file_mtime) { // file has been modified shader_file_mtime = (int)attr.st_mtime; reloadShader(); } } } // update camera (-z: forward, y: up) camera_euler_angles += 2.0f*delta_time * v3(-movement_command.rotate.x, -movement_command.rotate.y, 0.0f); camera_euler_angles.x = fminf(fmaxf(-0.5f*(float)M_PI, camera_euler_angles.x), 0.5f*(float)M_PI); // clamp mat3 rot_x = rotationMatrix(v3(1.0f, 0.0f, 0.0f), camera_euler_angles.x); mat3 rot_y = rotationMatrix(v3(0.0f, 1.0f, 0.0f), camera_euler_angles.y); mat3 rot_z = rotationMatrix(v3(0.0f, 0.0f, 1.0f), camera_euler_angles.z); mat3 rot = rot_y * rot_x * rot_z; camera_location += rot * (8.0f*delta_time*movement_command.move); mat4 view_to_world = translationMatrix(camera_location) * m4(rot); mat4 world_to_view = m4(transpose(rot)) * translationMatrix(-camera_location); // bind textures for (int tsi = 0; tsi < (int)ARRAY_COUNT(texture_slots); tsi++) { glActiveTexture(GL_TEXTURE0+tsi); glBindTexture(texture_slots[tsi].target, texture_slots[tsi].texture); } // draw fullscreen triangle(s) glClearColor(0.2f, 0.21f, 0.22f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); { BindShader bind_shader(shader); if (!compile_error_log) { for (int i = 0; i < uniform_count; i++) { uniforms[i].apply(); } } // apply builtin uniforms u_time = (float)frame_count / 60.0f; glUniform1f(shader.getUniformLocation(u_time_name), u_time); vec2 u_resolution = v2(video.pixel_scale*video.width, video.pixel_scale*video.height); glUniform2fv(shader.getUniformLocation(u_resolution_name), 1, u_resolution.e); glUniformMatrix4fv(shader.getUniformLocation(u_view_to_world_name), 1, GL_FALSE, view_to_world.e); glUniformMatrix4fv(shader.getUniformLocation(u_world_to_view_name), 1, GL_FALSE, world_to_view.e); if (single_triangle_mode) { { BindArrayBuffer bind_array_buffer(single_triangle_vbo); glEnableVertexAttribArray(VAT_POSITION); glVertexAttribPointer(VAT_POSITION, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(VAT_POSITION); } } else { { BindArrayBuffer bind_array_buffer(two_triangles_vbo); glEnableVertexAttribArray(VAT_POSITION); glVertexAttribPointer(VAT_POSITION, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableVertexAttribArray(VAT_POSITION); } } } }