Matrix4 Matrix4::Inverse() const { Matrix4 m; GLfloat det = Determinant(); if(fabs(det) < 0.000001f) return(m); for(GLuint c=0; c<4; c++) for(GLuint r=0; r<4; r++) m.mat[c*4+r]=Cofactor(c, r)/det; return(m.Transpose()); }
void NodeIntersector<real>::TransformIntersectionToGlobalCoordinates( const CoreLib::Node<real>* node, Intersection<real>& ioIntersection ) { // newPosition = M * position // newNormal = M^{-T} * normal const Matrix4<real>& localToGlobal = node->GetLocalToGlobal(); Matrix4<real> localToGlobalForNormals = node->GetGlobalToLocal(); localToGlobalForNormals.Transpose(); ioIntersection.SetPosition( localToGlobal * ioIntersection.GetPosition() ); ioIntersection.SetNormal( localToGlobalForNormals ^ ioIntersection.GetNormal() ); }
void SpriteShader::SetParameter(const std::string ¶meterName, const Matrix4 &value) { if(pimpl->uniforms.find(parameterName) == pimpl->uniforms.end()) throw std::runtime_error("Couldn't find the named SpriteEffect parameter: " + parameterName); auto &uniformData = pimpl->uniforms[parameterName]; if(uniformData.type != GL_FLOAT_MAT4) throw std::runtime_error("Type mismatch for named SpriteEffect paramater: " + parameterName); glUniformMatrix4fv(uniformData.location, 1, GL_FALSE, value.Transpose()); }
void Frustum::Transform(const Matrix4& m) { MATH_FUNCTION_TIMER(); Matrix4 inv = m.Inverted(); inv.Transpose(); top.Transform(inv); bottom.Transform(inv); left.Transform(inv); right.Transform(inv); front.Transform(inv); back.Transform(inv); }
Matrix4 Camera3D::GetCameraViewMatrix(){ //get transform matrix Matrix4 cameraTransformMatrix; cameraTransformMatrix.Translate(m_position); cameraTransformMatrix.m_translation.x *= -1.0f; //stopgap fix for -zUP issue cameraTransformMatrix.m_translation.z *= -1.0f; //stopgap fix for -zUP issue Matrix4 viewMatrix = /* GetCameraRotationMatrix() * */ cameraTransformMatrix * GetCameraRotationMatrix(); //R*T = rotate around origin, movement correct //T*R = rotate correct, absolute movement viewMatrix.Transpose(); //the movement is absolute regardless of rotation for whatever reason... return viewMatrix; }
bool Gizmo::Manipulate(const Camera* camera, const ea::vector<WeakPtr<Node>>& nodes) { if (nodes.empty()) return false; ImGuizmo::SetOrthographic(camera->IsOrthographic()); if (!IsActive()) { if (nodes.size() > 1) { // Find center point of all nodes // It is not clear what should be rotation and scale of center point for multiselection, therefore we limit // multiselection operations to world space (see above). Vector3 center = Vector3::ZERO; auto count = 0; for (const auto& node: nodes) { if (node.Expired() || node->GetType() == Scene::GetTypeStatic()) continue; center += node->GetWorldPosition(); count++; } if (count == 0) return false; center /= count; currentOrigin_.SetTranslation(center); } else if (!nodes.front().Expired()) currentOrigin_ = nodes.front()->GetTransform().ToMatrix4(); } // Enums are compatible. auto operation = static_cast<ImGuizmo::OPERATION>(operation_); ImGuizmo::MODE mode = ImGuizmo::WORLD; // Scaling only works in local space. Multiselections only work in world space. if (transformSpace_ == TS_LOCAL) mode = ImGuizmo::LOCAL; else if (transformSpace_ == TS_WORLD) mode = ImGuizmo::WORLD; // Scaling is always done in local space even for multiselections. if (operation_ == GIZMOOP_SCALE) mode = ImGuizmo::LOCAL; // Any other operations on multiselections are done in world space. else if (nodes.size() > 1) mode = ImGuizmo::WORLD; Matrix4 view = camera->GetView().ToMatrix4().Transpose(); Matrix4 proj = camera->GetProjection().Transpose(); Matrix4 tran = currentOrigin_.Transpose(); Matrix4 delta; ImGuiIO& io = ImGui::GetIO(); auto pos = displayPos_; auto size = displaySize_; if (size.x == 0 && size.y == 0) size = io.DisplaySize; ImGuizmo::SetRect(pos.x, pos.y, size.x, size.y); ImGuizmo::Manipulate(&view.m00_, &proj.m00_, operation, mode, &tran.m00_, &delta.m00_, nullptr); if (IsActive()) { if (!wasActive_) { // Just started modifying nodes. for (const auto& node: nodes) initialTransforms_[node] = node->GetTransform(); } wasActive_ = true; tran = tran.Transpose(); delta = delta.Transpose(); currentOrigin_ = Matrix4(tran); for (const auto& node: nodes) { if (node == nullptr) { URHO3D_LOGERROR("Gizmo received null pointer of node."); continue; } if (operation_ == GIZMOOP_SCALE) { // A workaround for ImGuizmo bug where delta matrix returns absolute scale value. if (!nodeScaleStart_.contains(node)) nodeScaleStart_[node] = node->GetScale(); node->SetScale(nodeScaleStart_[node] * delta.Scale()); } else { // Delta matrix is always in world-space. if (operation_ == GIZMOOP_ROTATE) node->RotateAround(currentOrigin_.Translation(), -delta.Rotation(), TS_WORLD); else node->Translate(delta.Translation(), TS_WORLD); } } return true; } else { if (wasActive_) { // Just finished modifying nodes. using namespace GizmoNodeModified; for (const auto& node: nodes) { if (node.Expired()) { URHO3D_LOGWARNINGF("Node expired while manipulating it with gizmo."); continue; } auto it = initialTransforms_.find(node.Get()); if (it == initialTransforms_.end()) { URHO3D_LOGWARNINGF("Gizmo has no record of initial node transform. List of transformed nodes " "changed mid-manipulation?"); continue; } SendEvent(E_GIZMONODEMODIFIED, P_NODE, node.Get(), P_OLDTRANSFORM, it->second, P_NEWTRANSFORM, node->GetTransform()); } } wasActive_ = false; initialTransforms_.clear(); if (operation_ == GIZMOOP_SCALE && !nodeScaleStart_.empty()) nodeScaleStart_.clear(); } return false; }
void Matrix4::Adjoint( Matrix4* adjoint ) const { Matrix4 cofactor; Cofactor( &cofactor ); cofactor.Transpose( adjoint ); }
Matrix4 InverseMVP(const Matrix4 &invP, const Vector3 &T, const Matrix4 &R) { return R.Transpose() * Matrix4::Translation(T).Transpose() * invP; }
Transform RotationTransform(float radians, float x, float y, float z) { const Matrix4 mat = RotationMatrix(radians, x, y, z); const Matrix4 inv = mat.Transpose(); return Transform(mat, inv); }
void Shader::RecompileInternal(BaseObject * caller, void * param, void *callerData) { DVASSERT((vertexShader == 0) && (fragmentShader == 0) && (program == 0)); if (!CompileShader(&vertexShader, GL_VERTEX_SHADER, vertexShaderData->GetSize(), (GLchar*)vertexShaderData->GetPtr(), vertexShaderDefines)) { Logger::Error("Failed to compile vertex shader: %s", vertexShaderPath.GetAbsolutePathname().c_str()); return; } if (!CompileShader(&fragmentShader, GL_FRAGMENT_SHADER, fragmentShaderData->GetSize(), (GLchar*)fragmentShaderData->GetPtr(), fragmentShaderDefines)) { Logger::Error("Failed to compile fragment shader: %s", fragmentShaderPath.GetAbsolutePathname().c_str()); return; } program = glCreateProgram(); RENDER_VERIFY(glAttachShader(program, vertexShader)); RENDER_VERIFY(glAttachShader(program, fragmentShader)); if (!LinkProgram(program)) { Logger::Error("Failed to Link program for shader: %s", fragmentShaderPath.GetAbsolutePathname().c_str()); DeleteShaders(); return; } RENDER_VERIFY(glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &activeAttributes)); char attributeName[512]; attributeNames = new FastName[activeAttributes]; for (int32 k = 0; k < activeAttributes; ++k) { GLint size; GLenum type; RENDER_VERIFY(glGetActiveAttrib(program, k, 512, 0, &size, &type, attributeName)); attributeNames[k] = attributeName; int32 flagIndex = GetAttributeIndexByName(attributeName); vertexFormatAttribIndeces[flagIndex] = glGetAttribLocation(program, attributeName); } RENDER_VERIFY(glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &activeUniforms)); SafeDeleteArray(uniformOffsets); SafeDeleteArray(uniformData); int32 totalSize = 0; uniformOffsets = new uint16[activeUniforms]; for (int32 k = 0; k < activeUniforms; ++k) { GLint size; GLenum type; RENDER_VERIFY(glGetActiveUniform(program, k, 512, 0, &size, &type, attributeName)); uniformOffsets[k] = (uint16)totalSize; int32 uniformDataSize = GetUniformTypeSize((eUniformType)type); totalSize += sizeof(Uniform) + (uniformDataSize * size); } uniformData = new uint8[totalSize]; for (int32 k = 0; k < activeUniforms; ++k) { GLint size = 0; GLenum type = 0; RENDER_VERIFY(glGetActiveUniform(program, k, 512, 0, &size, &type, attributeName)); Uniform* uniformStruct = GET_UNIFORM(k); new (&uniformStruct->name) FastName(); //VI: FastName is not a POD so a constructor should be called eUniform uniform = GetUniformByName(attributeName); uniformStruct->name = attributeName; uniformStruct->location = glGetUniformLocation(program, uniformStruct->name.c_str()); uniformStruct->id = uniform; uniformStruct->type = (eUniformType)type; uniformStruct->size = size; uniformStruct->cacheValueSize = GetUniformTypeSize((eUniformType)type) * size; uniformStruct->cacheValue = uniformData + uniformOffsets[k] + sizeof(Uniform); //VI: initialize cacheValue with value from shader switch(uniformStruct->type) { case UT_FLOAT: { RENDER_VERIFY(glGetUniformfv(program, uniformStruct->location, (float32*)uniformStruct->cacheValue)); break; } case UT_FLOAT_VEC2: { RENDER_VERIFY(glGetUniformfv(program, uniformStruct->location, (float32*)uniformStruct->cacheValue)); break; } case UT_FLOAT_VEC3: { RENDER_VERIFY(glGetUniformfv(program, uniformStruct->location, (float32*)uniformStruct->cacheValue)); break; } case UT_FLOAT_VEC4: { RENDER_VERIFY(glGetUniformfv(program, uniformStruct->location, (float32*)uniformStruct->cacheValue)); break; } case UT_INT: { RENDER_VERIFY(glGetUniformiv(program, uniformStruct->location, (int32*)uniformStruct->cacheValue)); break; } case UT_INT_VEC2: { RENDER_VERIFY(glGetUniformiv(program, uniformStruct->location, (int32*)uniformStruct->cacheValue)); break; } case UT_INT_VEC3: { RENDER_VERIFY(glGetUniformiv(program, uniformStruct->location, (int32*)uniformStruct->cacheValue)); break; } case UT_INT_VEC4: { RENDER_VERIFY(glGetUniformiv(program, uniformStruct->location, (int32*)uniformStruct->cacheValue)); break; } case UT_BOOL: { RENDER_VERIFY(glGetUniformiv(program, uniformStruct->location, (int32*)uniformStruct->cacheValue)); break; } case UT_BOOL_VEC2: { RENDER_VERIFY(glGetUniformiv(program, uniformStruct->location, (int32*)uniformStruct->cacheValue)); break; } case UT_BOOL_VEC3: { RENDER_VERIFY(glGetUniformiv(program, uniformStruct->location, (int32*)uniformStruct->cacheValue)); break; } case UT_BOOL_VEC4: { RENDER_VERIFY(glGetUniformiv(program, uniformStruct->location, (int32*)uniformStruct->cacheValue)); break; } //VI: Matrices are returned from the shader in column-major order so need to transpose the matrix. case UT_FLOAT_MAT2: { RENDER_VERIFY(glGetUniformfv(program, uniformStruct->location, (float32*)uniformStruct->cacheValue)); Matrix2* m = (Matrix2*)uniformStruct->cacheValue; Matrix2 t; for (int i = 0; i < 2; ++i) for (int j = 0; j < 2; ++j) t._data[i][j] = m->_data[j][i]; *m = t; break; } case UT_FLOAT_MAT3: { RENDER_VERIFY(glGetUniformfv(program, uniformStruct->location, (float32*)uniformStruct->cacheValue)); Matrix3* m = (Matrix3*)uniformStruct->cacheValue; Matrix3 t; for (int i = 0; i < 3; ++i) for (int j = 0; j < 3; ++j) t._data[i][j] = m->_data[j][i]; *m = t; break; } case UT_FLOAT_MAT4: { RENDER_VERIFY(glGetUniformfv(program, uniformStruct->location, (float32*)uniformStruct->cacheValue)); Matrix4* m = (Matrix4*)uniformStruct->cacheValue; m->Transpose(); break; } case UT_SAMPLER_2D: { RENDER_VERIFY(glGetUniformiv(program, uniformStruct->location, (int32*)uniformStruct->cacheValue)); break; } case UT_SAMPLER_CUBE: { RENDER_VERIFY(glGetUniformiv(program, uniformStruct->location, (int32*)uniformStruct->cacheValue)); break; } } } }