void QSceneNode::setPosition(const QVec3f& position) { if (signalsBlocked()) { const float* mat = 0; h3dGetNodeTransMats(m_hordeID, &mat, 0); // Normally this should never be occure, but in case of an invalid camera this may happen if (mat == 0) return; const_cast<float*>(mat)[12] = roundIt( position.X, 5 ); const_cast<float*>(mat)[13] = roundIt( position.Y, 5 ); const_cast<float*>(mat)[14] = roundIt( position.Z, 5 ); h3dSetNodeTransMat(m_hordeID, mat); m_xmlNode.setAttribute("tx", QString::number( position.X, 'f', 5 ) ); m_xmlNode.setAttribute("ty", QString::number( position.Y, 'f', 5 )); m_xmlNode.setAttribute("tz", QString::number( position.Z, 'f', 5 )); } else if (position != QSceneNode::position()) { static const QString undoText = tr("Set Position"); if (m_model->undoStack()->undoText() == undoText) m_model->undoStack()->push(new QXmlNodePropertyCommand(undoText, this, "Position", QVariant::fromValue(position), -1)); else m_model->undoStack()->push(new QXmlNodePropertyCommand(undoText, this, "Position", QVariant::fromValue(position), TransformationID)); } }
void QModelNode::activate() { float minX, minY, minZ, maxX, maxY, maxZ; h3dGetNodeAABB(m_hordeID, &minX, &minY, &minZ, &maxX, &maxY, &maxZ); unsigned int cameraID = HordeSceneEditor::instance()->glContext()->activeCam(); float leftPlane = h3dGetNodeParamF(cameraID, H3DCamera::LeftPlaneF, 0 ); float rightPlane = h3dGetNodeParamF(cameraID, H3DCamera::RightPlaneF, 0); float bottomPlane = h3dGetNodeParamF(cameraID, H3DCamera::BottomPlaneF, 0); float topPlane = h3dGetNodeParamF(cameraID, H3DCamera::TopPlaneF, 0); float nearPlane = h3dGetNodeParamF(cameraID, H3DCamera::NearPlaneF, 0); const float* camera = 0; H3DNode parentNode = h3dGetNodeParent(cameraID); h3dGetNodeTransMats(parentNode, 0, &camera); if ( !camera ) return; /** * (maxX - minX) = width of the bounding box * rightPlane / (rightPlane - leftPlane) = right fraction of the viewing frustum */ float offsetX = (maxX - minX) * rightPlane / (rightPlane - leftPlane); float offsetY = (maxY - minY) * topPlane / (topPlane - bottomPlane); QMatrix4f newCamTrans = QMatrix4f::TransMat(maxX - offsetX, maxY - offsetY, maxZ); newCamTrans.translate(0, 0, qMax(nearPlane * offsetX / rightPlane, nearPlane * offsetY / topPlane)); h3dSetNodeTransMat(cameraID, (QMatrix4f(camera).inverted() * newCamTrans).x); }
void pickRay( H3DNode cameraNode, float nwx, float nwy, float *ox, float *oy, float *oz, float *dx, float *dy, float *dz ) { // Transform from normalized window [0, 1] // to normalized device coordinates [-1, 1] float cx( 2.0f * nwx - 1.0f ); float cy( 2.0f * nwy - 1.0f ); // Get projection matrix Matrix4f projMat; h3dGetCameraProjMat( cameraNode, projMat.x ); // Get camera view matrix const float *camTrans; h3dGetNodeTransMats( cameraNode, 0x0, &camTrans ); Matrix4f viewMat( camTrans ); viewMat = viewMat.inverted(); // Create inverse view-projection matrix for unprojection Matrix4f invViewProjMat = (projMat * viewMat).inverted(); // Unproject Vec4f p0 = invViewProjMat * Vec4f( cx, cy, -1, 1 ); Vec4f p1 = invViewProjMat * Vec4f( cx, cy, 1, 1 ); p0.x /= p0.w; p0.y /= p0.w; p0.z /= p0.w; p1.x /= p1.w; p1.y /= p1.w; p1.z /= p1.w; if( h3dGetNodeParamI( cameraNode, H3DCamera::OrthoI ) == 1 ) { float frustumWidth = h3dGetNodeParamF( cameraNode, H3DCamera::RightPlaneF, 0 ) - h3dGetNodeParamF( cameraNode, H3DCamera::LeftPlaneF, 0 ); float frustumHeight = h3dGetNodeParamF( cameraNode, H3DCamera::TopPlaneF, 0 ) - h3dGetNodeParamF( cameraNode, H3DCamera::BottomPlaneF, 0 ); Vec4f p2( cx, cy, 0, 1 ); p2.x = cx * frustumWidth * 0.5f; p2.y = cy * frustumHeight * 0.5f; viewMat.x[12] = 0; viewMat.x[13] = 0; viewMat.x[14] = 0; p2 = viewMat.inverted() * p2; *ox = camTrans[12] + p2.x; *oy = camTrans[13] + p2.y; *oz = camTrans[14] + p2.z; } else { *ox = camTrans[12]; *oy = camTrans[13]; *oz = camTrans[14]; } *dx = p1.x - p0.x; *dy = p1.y - p0.y; *dz = p1.z - p0.z; }
QMatrix4f QSceneNode::relTrans() const { if( m_hordeID == 0) return QMatrix4f(); const float* mat = 0; h3dGetNodeTransMats(m_hordeID, &mat, 0); if( mat ) return QMatrix4f(mat); else return QMatrix4f(); }
void Joint::update() { const float* rel; const float* abs; h3dGetNodeTransMats( m_horde_id, &rel, &abs ); m_transf_rel = Horde3D::Matrix4f(rel); m_transf_abs = Horde3D::Matrix4f(abs); }
Vector2 Camera::worldToViewport(const Vector3 &worldCoordinates) const { const float *nodeTrans; h3dGetNodeTransMats(cameraNode, 0, &nodeTrans); Matrix4 view = Matrix4(nodeTrans).inverted(); Vector4 v = projMat * view * Vector4(worldCoordinates); float invW = 1.0f / v.w; return Vector2(v.x * invW, -v.y * invW); }
Vec3f utils::getEntityPosition(int eID) { const float *x; //GameEvent getTransformation(GameEvent::E_TRANSFORMATION, x, 0); //GameEngine::sendEvent(eID, &getTransformation); //we'll query the transformaiton data from H3D directly so we get the most recent values unsigned int hID = GameEngine::entitySceneGraphID(eID); h3dGetNodeTransMats(hID, 0, &x); return Vec3f(x[12],x[13],x[14]); }
void SceneGraphComponent::setHordeID( H3DNode id ) { m_hordeID = id; if( id != 0 ) { const float* t = 0x0; h3dGetNodeTransMats(id, 0, &t); // Copy absolute transformation of scene graph resource to the member variable if( t != 0x0 ) memcpy(m_transformation, t, sizeof(float) * 16); else GameLog::errorMessage("Error retrieving absolute transformation matrix for HordeID %d", id); } }
void SceneGraphComponent::checkTransformation() { // Check if transformation has been changed (e.g. by a transformation change of a parent node) if ( m_hordeID > 0 && h3dCheckNodeTransFlag( m_hordeID, true ) ) { // Update the locally stored global transformation const float* absTrans = 0; h3dGetNodeTransMats(m_hordeID, 0, &absTrans); memcpy(m_transformation, absTrans, sizeof(float) * 16); GameEvent event(GameEvent::E_SET_TRANSFORMATION, GameEventData(m_transformation, 16), this); m_owner->executeEvent(&event); m_visibilityFlag = 0; } }
void SceneGraphComponent::sendTransformation() { if (m_hordeID > 0) { // printf("Inside send Transformation with hID: %d\n", m_hordeID); const float* parentMat = 0; // since the event transformation is absolute we have to create a relative transformation matrix for Horde3D h3dGetNodeTransMats(h3dGetNodeParent(m_hordeID), 0, &parentMat); if (parentMat) h3dSetNodeTransMat(m_hordeID, (Matrix4f(parentMat).inverted() * Matrix4f(m_transformation)).x); else printf("no parent MAT\n"); // ensure reset of Horde3D transformation flag since we have updated it from the GameEngine and such don't need to be informed // when calling SceneGraphComponent::update() (note that the node transformed flag will be set again if someone else will update // the transformation from outside, so this way of avoiding unnecessary updates should be safe) h3dCheckNodeTransFlag( m_hordeID, true ); //printf("SceneGraphComponent::setTransformation\n\t %.3f, %.3f, %.3f\n", transformation[12], transformation[13], transformation[14]); m_visibilityFlag = 0; } }
void SceneGraphComponent::loadFromXml( const XMLNode* description ) { const char* id = description->getAttribute("id", "0"); int newID = atoi(id); // Remove component if( newID == 0 && m_hordeID != 0) { m_hordeID = newID; SceneGraphManager::instance()->removeComponent(this); GameLog::errorMessage( " No valid Horde3D ID for SceneGraphComponent in entity '%s'", m_owner->id().c_str() ); } // Change component else if ( m_hordeID != 0 && m_hordeID != newID ) { GameLog::errorMessage(" Warning: The scene graph component for entity '%s' has been already initialized with '%d' Untested behavior!", m_owner->id().c_str(), m_hordeID); } // if( newID != 0 ) { m_hordeID = newID; const float* trans = 0; h3dGetNodeTransMats(m_hordeID, 0, &trans); if( trans ) { SceneGraphManager::instance()->addComponent(this); memcpy( m_transformation, trans, sizeof( float ) * 16 ); m_visibilityFlag = 0; } else { m_hordeID = 0; SceneGraphManager::instance()->removeComponent(this); GameLog::errorMessage("Entity '%s': The ID '%d' seems to be no valid Horde3D ID!", m_owner->id().c_str(), newID); } } }
void Camera::_update() { Utils::Vec3f pos = _relative + _target; Utils::Vec3f angle = (-_relative).toRotation(); angle.x = Utils::radToDeg(angle.x); angle.y = Utils::radToDeg(angle.y); angle.z = Utils::radToDeg(angle.z); h3dSetNodeTransform( handle, pos.x, pos.y, pos.z, angle.x, angle.y, angle.z, //angle.x, angle.y, angle.z, 1.0, 1.0, 1.0); const float* mat_data; h3dGetNodeTransMats(handle, nullptr, &mat_data); _inv_modelview_mat = Utils::Matrix4f(mat_data).inverted(); Utils::Matrix4f::fastMult43(_screenspace_mat, _proj_mat, _inv_modelview_mat); return; }
Matrix4 Camera::getViewMatrix() const { const float* view = 0; h3dGetNodeTransMats(cameraNode, 0, &view); return Matrix4(view).inverted(); }
void GazeComponent::headShake(int axis, float extent, int count, float speed, float duration) { //get head position h3dFindNodes( m_hID, Config::getParamS( Agent_Param::HeadName_S ), H3DNodeTypes::Joint ); int head_hID = h3dGetNodeFindResult(0); if(head_hID <= 0) return; const float *head_absArray; h3dGetNodeTransMats( head_hID, 0, &head_absArray ); Vec3f head_pos(head_absArray[12], head_absArray[13], head_absArray[14]); //check parameters if(count < 0) count = Config::getParamI(Agent_Param::DfltHeadShakeReps_I); if(extent < 0) extent = Config::getParamF(Agent_Param::DfltHeadShakeExt_F); if(speed < 0) speed = Config::getParamF(Agent_Param::DfltHeadShakeSpd_F); if(duration < 0) duration = Config::getParamF(Agent_Param::DfltHeadShakeDur_F); if(axis < 0 || axis > 2) axis = Config::getParamI(Agent_Param::DfltHeadShakeAxis_I); Vec3f deviation(0,0,0); switch((utils::Axis::List)axis) { case utils::Axis::X: deviation.x = extent; break; case utils::Axis::Y: deviation.y = extent; break; case utils::Axis::Z: deviation.z = extent; break; } Vec3f p,r,s; Matrix4f head_absMat(head_absArray); head_absMat.decompose(p,r,s); Vec3f currentGaze = getGazeCoord(); //convert current gaze to head coord sys currentGaze = head_absMat.inverted() * currentGaze; //compute target vectors Vec3f targetGaze1 = currentGaze - deviation; Vec3f targetGaze2 = currentGaze + deviation; //conver them to world coord sys targetGaze1 = head_absMat * targetGaze1; targetGaze2 = head_absMat * targetGaze2; std::list<Gaze*> nodes; for(int i=0; i<count; i++) { nodes.push_back( new Gaze(this, getGazeCoord(), (i%2 == 0)? targetGaze1 : targetGaze2, (speed >= 0)? speed : m_speed, duration) ); } //now add the new gaze nodes to the gaze stack (in reverse order ... 'cause it's a stack) std::list<Gaze*>::reverse_iterator riter = nodes.rbegin(); while(riter != nodes.rend()) { if((*riter)->isValid()) m_gazeNodes.push( (*riter) ); ++riter; } }