예제 #1
0
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());
}
예제 #2
0
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() );
}
예제 #3
0
 void SpriteShader::SetParameter(const std::string &parameterName, 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());
 }
예제 #4
0
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);
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
void Matrix4::Adjoint( Matrix4* adjoint ) const
{
	Matrix4 cofactor;
	Cofactor( &cofactor );
	cofactor.Transpose( adjoint );
}
예제 #8
0
파일: Misc.cpp 프로젝트: bizz84/biz-engine
Matrix4 InverseMVP(const Matrix4 &invP, const Vector3 &T, const Matrix4 &R)
{
	return R.Transpose() * Matrix4::Translation(T).Transpose() * invP;
}
예제 #9
0
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);
}
예제 #10
0
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;
			}
		}
    }
}