void PhysicsComponent::sendTransformation(const btTransform& transformation, bool apply) { #ifdef BT_USE_DOUBLE_PRECISION double m[16]; transformation.getBasis().scaled(m_collisionShape->getLocalScaling()).getOpenGLSubMatrix(m); float x[16]; x[0] = m[0]; x[1] = m[1]; x[2] = m[2]; x[3] = m[3]; x[4] = m[4]; x[5] = m[5]; x[6] = m[6]; x[7] = m[7]; x[8] = m[8]; x[9] = m[9]; x[10] = m[10]; x[11] = m[11]; x[12] = transformation.getOrigin().x(); x[13] = transformation.getOrigin().y(); x[14] = transformation.getOrigin().z(); x[15] = 1.0f; #else float x[16]; btMatrix3x3 scaledBasis = transformation.getBasis().scaled(m_collisionShape->getLocalScaling()); btVector3 voffset = scaledBasis * btVector3(lX, lY, lZ); transformation.getBasis().scaled(m_collisionShape->getLocalScaling()).getOpenGLSubMatrix(x); x[12] = transformation.getOrigin().x(); x[13] = transformation.getOrigin().y(); x[14] = transformation.getOrigin().z(); x[15] = 1.0f; #endif // Merge scaling with scale free transformation #ifdef DEBUG GameEvent proxy_event(GameEvent::E_SET_TRANSFORMATION, &GameEventData(x, 16), this); if (m_proxy) { // printf("PhysicsComponent::update: %.3f, %.3f, %.3f\n", x[12], x[13], x[14]); // printf("SENDING PROXY A TRANSFORMATION"); if (m_proxy->checkEvent(&proxy_event)) m_proxy->executeEvent(&proxy_event); //return; } #endif x[12] = transformation.getOrigin().x() - voffset.x(); x[13] = transformation.getOrigin().y() - voffset.y(); x[14] = transformation.getOrigin().z() - voffset.z(); GameEvent event(GameEvent::E_SET_TRANSFORMATION, &GameEventData(x, 16), this); if (m_owner->checkEvent(&event)) { // printf("PhysicsComponent::update: %.3f, %.3f, %.3f\n", x[12], x[13], x[14]); m_owner->executeEvent(&event); if (apply) setTransformation(x); } else { // Reset Physics State to original transformation GameEvent e(GameEvent::E_TRANSFORMATION, GameEventData((float*) x, 16), this); m_owner->executeEvent(&e); setTransformation(x); // deactivate object until it is reactivated again by another collision or physics adjustment m_rigidBody->setActivationState(WANTS_DEACTIVATION); } }
void GUISoundManager::update(vector<string> eventCompList) { if (enabled) { if (fadeIN && fadeGain >= backgroundGain) { fadeIN = false; setBackgroundGain(backgroundGain); } if (fadeIN && play) { fadeGain += ( backgroundGain/GameEngine::FPS())/5.0f; if (backgroundSounds.size()>0) { for (unsigned int i = 0; i < backgroundSounds.size(); i++) { GameEvent eve(GameEvent::E_SET_SOUND_GAIN, &GameEventData(fadeGain), 0x0); GameEngine::sendEvent(backgroundSounds[i], &eve); } } } if (fadeOUT && fadeGain <= 0) { stopBackgroundMusic(); fadeOUT = false; for (unsigned int i = 0; i < eventCompList.size(); i++) { GUIEventData::sendToComp(new GUIEventData(O_GUI_SOUND_FADEDOUT,L"GUISoundManager"),eventCompList.at(i).c_str()); } } if (fadeOUT && play) { fadeGain -= ( backgroundGain/GameEngine::FPS())/2.0f; if (backgroundSounds.size()>0) { for (unsigned int i = 0; i < backgroundSounds.size(); i++) { GameEvent eve(GameEvent::E_SET_SOUND_GAIN, &GameEventData(fadeGain), 0x0); GameEngine::sendEvent(backgroundSounds[i], &eve); } } } if (backgroundSounds.size()>0) { bool playing = false; GameEvent isPlaying(GameEvent::E_GET_SOUND_ISPLAYING, &GameEventData(&playing), 0x0); GameEngine::sendEvent(backgroundSounds[backgroundTitle], &isPlaying); if (!playing && play) playNextBackgroundMusic(); } } }
VideoComponent::VideoComponent(GameEntity* owner) : GameComponent(owner, "VideoComponent"), m_startTime(0), m_data(0x0), m_playing(false), m_material(0), m_resize(false), m_bgraData(0x0), m_pgf(0x0), m_videoTexture(0), m_samplerIndex(-1), m_originalSampler(0), m_autoStart(false), m_loop(false), m_startNextFrame(false), m_newData(false), m_hasAudio(false), m_camId(0) { VideoManager::instance()->addComponent(this); // We need our own access to the com library for not disturbing others (like the SapiComponent) CoInitializeEx(NULL, COINIT_MULTITHREADED); // Listen to cam changes owner->addListener(GameEvent::E_ACTIVE_CAM_CHANGE, this); // And get the current one // First the GameEngine id int camID = 0; GameEvent camEvent(GameEvent::E_GET_ACTIVE_CAM, &GameEventData(&camID), this); GameModules::gameWorld()->executeEvent(&camEvent); // Then the entity GameEntity* camEntity = GameModules::gameWorld()->entity(camID); if (camEntity) { // And finally the horde id, puh! GameEvent getHordeID(GameEvent::E_GET_SCENEGRAPH_ID, &m_camId, this); camEntity->executeEvent(&getHordeID); } m_hdd = DrawDibOpen(); m_hdc = CreateCompatibleDC(0); }
void VideoComponent::playAvi() { if (m_playing) { // Already playing, so stop first to restart stopAvi(); // And start the next frame (so the Sound Component will be able to stop the sound before) m_startNextFrame = true; } else if (m_pgf != 0x0 && m_material != 0 && m_videoTexture != 0 && m_samplerIndex != -1) { // And apply the new video texture as sampler to the material h3dSetResParamI(m_material, H3DMatRes::SamplerElem, m_samplerIndex, H3DMatRes::SampTexResI, m_videoTexture); m_startTime = GameEngine::currentTimeStamp(); m_playing = true; if (m_hasAudio) { // Play the previously loaded sound GameEvent enableSound(GameEvent::E_SET_ENABLED, &GameEventData(true), this); m_owner->executeEvent(&enableSound); } } }
void SceneGraphComponent::traject() { // apply trajections if (m_net_applyTrajection) { // apply translation m_transformation[12] += m_net_traject_translation.x * m_net_traject_speedup; m_transformation[13] += m_net_traject_translation.y * m_net_traject_speedup; m_transformation[14] += m_net_traject_translation.z * m_net_traject_speedup; // apply rotation Matrix4f trans( Matrix4f(m_transformation) * Matrix4f(Quaternion( m_net_traject_rotation.x * m_net_traject_speedup, m_net_traject_rotation.y * m_net_traject_speedup, m_net_traject_rotation.z * m_net_traject_speedup )) ); memcpy( m_transformation, trans.x, sizeof( float ) * 16 ); // TODO: apply scale sendTransformation(); GameEvent event(GameEvent::E_SET_TRANSFORMATION, GameEventData(m_transformation, 16), this); m_owner->executeEvent(&event); } }
void SceneGraphComponent::setScale(const Vec3f *scale) { /*Vec3f tr,rotation,sc; Matrix4f(m_transformation).decompose(tr,rotation,sc); Matrix4f trans = Matrix4f::ScaleMat( scale->x, scale->y, scale->z ); trans = trans * Matrix4f(Quaternion(rotation.x, rotation.y, rotation.z)); trans.translate(m_transformation[12], m_transformation[13], m_transformation[14]); GameEvent event(GameEvent::E_SET_TRANSFORMATION, GameEventData(trans.x, 16), 0);*/ Vec3f tr,rotation,sc; Matrix4f(m_transformation).decompose(tr,rotation,sc); Matrix4f trans = Matrix4f::ScaleMat( scale->x, scale->y, scale->z ); trans = trans * Matrix4f(Quaternion(rotation.x, rotation.y, rotation.z)); trans.translate(tr.x, tr.y, tr.z); GameEvent event(GameEvent::E_SET_TRANSFORMATION, GameEventData(trans.x, 16), this); if (m_owner->checkEvent(&event)) { // Apply the new transformation memcpy( m_transformation, trans.x, sizeof( float ) * 16 ); // Send it to horde sendTransformation(); //and to the other components m_owner->executeEvent(&event); } }
void SceneGraphComponent::translateGlobal(const Vec3f* translation) { // ensure that m_transfomration is up to date checkTransformation(); /*Matrix4f trans(m_transformation); trans.x[12] += translation->x; trans.x[13] += translation->y; trans.x[14] += translation->z; GameEvent event(GameEvent::E_SET_TRANSFORMATION, GameEventData(trans.x, 16), 0);*/ // Backup trans Vec3f transBackup(m_transformation[12], m_transformation[13], m_transformation[14]); m_transformation[12] += translation->x; m_transformation[13] += translation->y; m_transformation[14] += translation->z; GameEvent event(GameEvent::E_SET_TRANSFORMATION, GameEventData(m_transformation, 16), this); if (m_owner->checkEvent(&event)) { // Send transformation to horde sendTransformation(); //and to the other components m_owner->executeEvent(&event); } else { // Revert changes m_transformation[12] = transBackup.x; m_transformation[13] = transBackup.y; m_transformation[14] = transBackup.z; } }
void GUISoundManager::stopBackgroundMusic() { if (enabled&& backgroundSounds.size()>0) { for (unsigned int i = 0; i < backgroundSounds.size(); ++i) { bool playing = false; GameEvent isPlaying(GameEvent::E_GET_SOUND_ISPLAYING, &GameEventData(&playing), 0x0); GameEngine::sendEvent(backgroundSounds[i], &isPlaying); if (playing) { GameEvent eve(GameEvent::E_STOP_SOUND, &GameEventData(), 0x0); GameEngine::sendEvent(backgroundSounds[i], &eve); } } play = false; } }
void GUISoundManager::setEventGain(float val) { if (eventSounds.size()>0) { eventGain = val; for (unsigned int i = 0; i < eventSounds.size(); i++) { GameEvent eve(GameEvent::E_SET_SOUND_GAIN, &GameEventData(val), 0x0); GameEngine::sendEvent(eventSounds[i]->getEntityID(), &eve); } } }
void GUISoundManager::setBackgroundGain(float val) { if (backgroundSounds.size()>0) { backgroundGain = val; for (unsigned int i = 0; i < backgroundSounds.size(); i++) { GameEvent eve(GameEvent::E_SET_SOUND_GAIN, &GameEventData(val), 0x0); GameEngine::sendEvent(backgroundSounds[i], &eve); } } }
void GUISoundManager::playBackgroundMusicWithFadeIn() { if (play == false && fadeIN == false) { fadeIN = true; fadeGain = 0; if (backgroundSounds.size()>0) { for (unsigned int i = 0; i < backgroundSounds.size(); i++) { GameEvent eve(GameEvent::E_SET_SOUND_GAIN, &GameEventData(0), 0x0); GameEngine::sendEvent(backgroundSounds[i], &eve); } } playBackgroundMusic(); } }
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 GUISoundManager::playBackgroundMusic() { if (play == false) { if (enabled && backgroundTitle >= 0 && (unsigned)backgroundTitle<backgroundSounds.size()) { bool playing = false; GameEvent isPlaying(GameEvent::E_GET_SOUND_ISPLAYING, &GameEventData(&playing), 0x0); GameEngine::sendEvent(backgroundSounds[backgroundTitle], &isPlaying); if (!playing) { GameEvent startSound(GameEvent::E_PLAY_SOUND, 0x0, 0x0); GameEngine::sendEvent(backgroundSounds[backgroundTitle], &startSound); play = true; } } } }
void VideoComponent::stopAvi() { if (m_playing) { if (m_originalSampler != 0 && m_samplerIndex != -1 && m_material != 0) // Reset original sampler texture h3dSetResParamI(m_material, H3DMatRes::SamplerElem, m_samplerIndex, H3DMatRes::SampTexResI, m_originalSampler); if (m_hasAudio) { // Stopping a sound is done by setting the gain to 0 GameEvent stopSound(GameEvent::E_SET_SOUND_GAIN, &GameEventData(0.0f), this); m_owner->executeEvent(&stopSound); } m_playing = false; } }
void VideoComponent::closeAvi() { // Stop it first as it might still be playing stopAvi(); // Unload the video if there is already one if (m_pgf) { delete[] m_bgraData; m_bgraData = 0x0; if (m_hBitmap) DeleteObject(m_hBitmap); // Delete The Device Dependant Bitmap Object if (m_pgf) AVIStreamGetFrameClose(m_pgf); // Deallocates The GetFrame Resources m_pgf = 0x0; if (m_pavi) AVIStreamRelease(m_pavi); // Release The Stream AVIFileExit(); // Release The File if (m_videoTexture) { // Remove video texture h3dRemoveResource(m_videoTexture); // And release it if unused now (should be, else we can't create the same again) h3dReleaseUnusedResources(); m_videoTexture = 0; m_originalSampler = 0; m_samplerIndex = 0; } if (m_hasAudio) { // Set an empty sound for releasing the old one GameEvent clearSound(GameEvent::E_SET_SOUND_FILE, &GameEventData(""), this); m_owner->executeEvent(&clearSound); m_hasAudio = false; } } }
void PhysicsComponent::loadFromXml(const XMLNode* description) { GameLog::logMessage("LOADING BULLET FROM XML"); // Delete old physics representation //release(); Matrix4f objTrans; m_owner->executeEvent(&GameEvent(GameEvent::E_TRANSFORMATION, &GameEventData((float*) objTrans.x, 16), this)); Vec3f t, r, s; objTrans.decompose(t, r, s); // Parse Physics Node Configuration float mass = static_cast<float>(atof(description->getAttribute("mass", "0.0"))); const char* shape = description->getAttribute("shape", "Box"); // create collision shape based on the node configuration if (shape && _stricmp(shape, "Box") == 0) // Bounding Box Shape { float dimX = static_cast<float>(atof(description->getAttribute("x", "1.0"))); float dimY = static_cast<float>(atof(description->getAttribute("y", "1.0"))); float dimZ = static_cast<float>(atof(description->getAttribute("z", "1.0"))); // update box settings with node scaling (TODO is this necessary if we already set the scale by using setLocalScaling?) //m_collisionShape = new btBoxShape(btVector3(dimX * s.x, dimY * s.y, dimZ * s.z)); m_collisionShape = new btBoxShape(btVector3(dimX, dimY, dimZ)); } else if (shape && _stricmp(shape, "Sphere") == 0) // Sphere Shape { float radius = static_cast<float>(atof(description->getAttribute("radius", "1.0"))); m_collisionShape = new btSphereShape(radius); } else if (shape && _stricmp(shape, "Cylinder") == 0) // Cylinder Shape { float radius0 = static_cast<float>(atof(description->getAttribute("radius", "1.0"))); float height = static_cast<float>(atof(description->getAttribute("height", "1.0"))); m_collisionShape = new btCylinderShape(btVector3(radius0, height, radius0)); } else // Mesh Shape { MeshData meshData; GameEvent meshEvent(GameEvent::E_MESH_DATA, &meshData, this); // get mesh data from graphics engine m_owner->executeEvent(&meshEvent); if (meshData.VertexBase && (meshData.TriangleBase32 || meshData.TriangleBase16)) { // Create new mesh in physics engine m_btTriangleMesh = new btTriangleMesh(); int offset = 3; if (meshData.TriangleMode == 5) // Triangle Strip offset = 1; // copy mesh from graphics to physics bool index16 = false; if (meshData.TriangleBase16) index16 = true; for (unsigned int i = 0; i < meshData.NumTriangleIndices - 2; i += offset) { unsigned int index1 = index16 ? (meshData.TriangleBase16[i] - meshData.VertRStart) * 3 : (meshData.TriangleBase32[i] - meshData.VertRStart) * 3; unsigned int index2 = index16 ? (meshData.TriangleBase16[i + 1] - meshData.VertRStart) * 3 : (meshData.TriangleBase32[i + 1] - meshData.VertRStart) * 3; unsigned int index3 = index16 ? (meshData.TriangleBase16[i + 2] - meshData.VertRStart) * 3 : (meshData.TriangleBase32[i + 2] - meshData.VertRStart) * 3; m_btTriangleMesh->addTriangle(btVector3(meshData.VertexBase[index1], meshData.VertexBase[index1 + 1], meshData.VertexBase[index1 + 2]), btVector3(meshData.VertexBase[index2], meshData.VertexBase[index2 + 1], meshData.VertexBase[index2 + 2]), btVector3(meshData.VertexBase[index3], meshData.VertexBase[index3 + 1], meshData.VertexBase[index3 + 2])); } bool useQuantizedAabbCompression = true; if (mass > 0) { //btGImpactMeshShape* shape = new btGImpactMeshShape(m_btTriangleMesh); btGImpactConvexDecompositionShape* shape = new btGImpactConvexDecompositionShape(m_btTriangleMesh, btVector3(1.f, 1.f, 1.f), btScalar(0.1f), true); shape->updateBound(); //btCollisionDispatcher* dispatcher = static_cast<btCollisionDispatcher *>(Physics::instance()->dispatcher()); //btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher); m_collisionShape = shape; //m_collisionShape = new btConvexTriangleMeshShape(m_btTriangleMesh); } else // BvhTriangleMesh can be used only for static objects m_collisionShape = new btBvhTriangleMeshShape(m_btTriangleMesh, useQuantizedAabbCompression); } else { GameLog::errorMessage("The mesh data for the physics representation couldn't be retrieved"); return; } } GameLog::logMessage("PARSED SHAPE FROM XML"); bool kinematic = _stricmp(description->getAttribute("kinematic", "false"), "true") == 0 || _stricmp(description->getAttribute("kinematic", "0"), "1") == 0; bool nondynamic = _stricmp(description->getAttribute("static", "false"), "true") == 0 || _stricmp(description->getAttribute("static", "0"), "1") == 0; bool ragdoll = _stricmp(description->getAttribute("ragdoll", "false"), "true") == 0 || _stricmp(description->getAttribute("ragdoll", "0"), "1") == 0; // Create initial transformation without scale btTransform tr; tr.setIdentity(); tr.setRotation(btQuaternion(r.x, r.y, r.z)); btMatrix3x3 rot = tr.getBasis(); XMLNode offsetXMLNode = description->getChildNode("Offset"); if (!offsetXMLNode.isEmpty()) { lX = static_cast<float>(atof(offsetXMLNode.getAttribute("lX", "0.0"))); lY = static_cast<float>(atof(offsetXMLNode.getAttribute("lY", "0.0"))); lZ = static_cast<float>(atof(offsetXMLNode.getAttribute("lZ", "0.0"))); } btVector3 offset = btVector3(lX * s.x, lY * s.y, lZ * s.z); tr.setOrigin(btVector3(t.x, t.y, t.z) + rot * offset); // Set local scaling in collision shape because Bullet does not support scaling in the world transformation matrices m_collisionShape->setLocalScaling(btVector3(s.x, s.y, s.z)); btVector3 localInertia(0, 0, 0); //rigidbody is dynamic if and only if mass is non zero otherwise static if (mass != 0) m_collisionShape->calculateLocalInertia(mass, localInertia); if (mass != 0 || kinematic) //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects m_motionState = new btDefaultMotionState(tr); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, m_motionState, m_collisionShape, localInertia); rbInfo.m_startWorldTransform = tr; //rbInfo.m_restitution = btScalar( atof(description->getAttribute("restitution", "0")) ); //rbInfo.m_friction = btScalar( atof(description->getAttribute("static_friction", "0.5")) ); // Threshold for deactivation of objects (if movement is below this value the object gets deactivated) //rbInfo.m_angularSleepingThreshold = 0.8f; //rbInfo.m_linearSleepingThreshold = 0.8f; m_rigidBody = new btRigidBody(rbInfo); m_rigidBody->setUserPointer(this); m_rigidBody->setDeactivationTime(2.0f); // Add support for collision detection if mass is zero but kinematic is explicitly enabled if (kinematic && mass == 0 && !nondynamic) { m_rigidBody->setCollisionFlags(m_rigidBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT); m_rigidBody->setActivationState(DISABLE_DEACTIVATION); } if (nondynamic && mass == 0) { m_rigidBody->setCollisionFlags(m_rigidBody->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT); } bool isTrigger = _stricmp(description->getAttribute("solid", "true"), "false") == 0 || _stricmp(description->getAttribute("solid", "1"), "0") == 0; if (isTrigger) { setCollisionResponse(true); } GameLog::logMessage("I'm a new Physics body: %s my Motion state: %d", m_owner->id().c_str(), m_motionState); printf("I'm a new Physics body: %s my Motion state: %d\n", m_owner->id().c_str(), m_motionState); if(!ragdoll) Physics::instance()->addObject(this); /*Geometry Proxy*/ XMLNode proxyXMLNode = description->getChildNode("Proxy"); if (proxyXMLNode.isEmpty()) return; m_proxy = GameModules::gameWorld()->entity(proxyXMLNode.getAttribute("name", "")); if (m_proxy) { m_proxy->addListener(GameEvent::E_SET_TRANSFORMATION, this); m_proxy->addListener(GameEvent::E_SET_TRANSLATION, this); m_proxy->addListener(GameEvent::E_SET_ROTATION, this); m_proxy->addListener(GameEvent::E_TRANSLATE_LOCAL, this); m_proxy->addListener(GameEvent::E_TRANSLATE_GLOBAL, this); m_proxy->addListener(GameEvent::E_ROTATE_LOCAL, this); } else printf("No PROXY FOUND with EntityID: %s\n", proxyXMLNode.getAttribute("name", "")); /*Adding constraints*/ XMLNode constraintXMLNode = description->getChildNode("Constraint"); if (constraintXMLNode.isEmpty()) return; const char* constraintType = constraintXMLNode.getAttribute("type", "Hinge"); const char* parentName = constraintXMLNode.getAttribute("parent", ""); PhysicsComponent* parent = getParent(parentName); if (!parent) { printf("NO PARENT FOUND\n"); return; } XMLNode transformXMLNode = constraintXMLNode.getChildNode("TransformA"); float qX = static_cast<float>(atof(transformXMLNode.getAttribute("qx", "1.0"))); float qY = static_cast<float>(atof(transformXMLNode.getAttribute("qy", "1.0"))); float qZ = static_cast<float>(atof(transformXMLNode.getAttribute("qz", "1.0"))); float qW = static_cast<float>(atof(transformXMLNode.getAttribute("qw", "1.0"))); float vX = static_cast<float>(atof(transformXMLNode.getAttribute("vx", "1.0"))); float vY = static_cast<float>(atof(transformXMLNode.getAttribute("vy", "1.0"))); float vZ = static_cast<float>(atof(transformXMLNode.getAttribute("vz", "1.0"))); btTransform transformA; transformA.setIdentity(); printf("%f \t %f \t %f \n ", qX, qY, qZ); transformA.getBasis().setEulerZYX(qZ, qY, qX); // transformA.getBasis().setEulerZYX(M_PI_2,0,0); transformA.setOrigin(btVector3(vX * s.x, vY * s.y, vZ * s.z)); // printf("%f \t %f \t %f \t %s \n ", vX*s.x, vY*s.y, vZ*s.z, m_owner ? m_owner->id().c_str() : "no name"); // btTransform transformA = btTransform(btQuaternion(qX, qY, qZ, qW), btVector3(vX*s.x, vY*s.y, vZ*s.z)); transformXMLNode = constraintXMLNode.getChildNode("TransformB"); qX = static_cast<float>(atof(transformXMLNode.getAttribute("qx", "1.0"))); qY = static_cast<float>(atof(transformXMLNode.getAttribute("qy", "1.0"))); qZ = static_cast<float>(atof(transformXMLNode.getAttribute("qz", "1.0"))); qW = static_cast<float>(atof(transformXMLNode.getAttribute("qw", "1.0"))); vX = static_cast<float>(atof(transformXMLNode.getAttribute("vx", "1.0"))); vY = static_cast<float>(atof(transformXMLNode.getAttribute("vy", "1.0"))); vZ = static_cast<float>(atof(transformXMLNode.getAttribute("vz", "1.0"))); // btTransform transformB = btTransform(btQuaternion(qX, qY, qZ, qW), btVector3(vX*s.x, vY*s.y, vZ*s.z)); btTransform transformB; transformB.setIdentity(); transformB.getBasis().setEulerZYX(qZ, qY, qX); // transformB.getBasis().setEulerZYX(M_PI_2,0,0); transformB.setOrigin(btVector3(vX * s.x, vY * s.y, vZ * s.z)); XMLNode limitXMLNode = constraintXMLNode.getChildNode("Limit"); if (_stricmp(constraintType, "Hinge") == 0) { btHingeConstraint* parentConstraint = new btHingeConstraint(*(parent->rigidBody()), *m_rigidBody, transformA, transformB); float low = static_cast<float>(atof(limitXMLNode.getAttribute("low", "0.0"))); float high = static_cast<float>(atof(limitXMLNode.getAttribute("high", "0.75"))); float softness = static_cast<float>(atof(limitXMLNode.getAttribute("softness", "0.9"))); float biasFactor = static_cast<float>(atof(limitXMLNode.getAttribute("biasFactor", "0.3"))); float relaxationFactor = static_cast<float>(atof(limitXMLNode.getAttribute("relaxationFactor", "1.0"))); parentConstraint->setLimit(low, high, softness, biasFactor, relaxationFactor); m_parentConstraint = parentConstraint; } else if (_stricmp(constraintType, "ConeTwist") == 0) { btConeTwistConstraint* parentConstraint = new btConeTwistConstraint(*(parent->rigidBody()), *m_rigidBody, transformA, transformB); float swingSpan1 = static_cast<float>(atof(limitXMLNode.getAttribute("swingSpan1", "1.0"))); float swingSpan2 = static_cast<float>(atof(limitXMLNode.getAttribute("swingSpan2", "1.0"))); float twistSpan = static_cast<float>(atof(limitXMLNode.getAttribute("twistSpan", "1.0"))); float softness = static_cast<float>(atof(limitXMLNode.getAttribute("softness", "0.9"))); float biasFactor = static_cast<float>(atof(limitXMLNode.getAttribute("biasFactor", "0.3"))); float relaxationFactor = static_cast<float>(atof(limitXMLNode.getAttribute("relaxationFactor", "1.0"))); parentConstraint->setLimit(swingSpan1, swingSpan2, twistSpan, softness, biasFactor, relaxationFactor); m_parentConstraint = parentConstraint; } if(!ragdoll) Physics::instance()->addConstraint(m_parentConstraint); }
void PhonemeEditorWidget::save() { blockSignals(true); //TODO: gaps between phonemes have to be interpreted as silence (phoneme "x") //Save changes to phoneme file if (!m_phonemeFileName.isEmpty() && m_saveButton->isEnabled()) { QFile file( QDir(GameEngine::soundResourceDirectory()).absoluteFilePath(m_phonemeFileName) ); if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { QTextStream stream(&file); m_phonemeXml.save(stream, 4); file.flush(); file.close(); } else { QMessageBox::warning(this, tr("Error"), tr("Error opening file %1 for writing:\n\n%2").arg(m_phonemeFileName).arg(file.errorString())); return; } } m_saveButton->setEnabled(false); GameEngine::sendEvent(m_entityWorldID, &GameEvent(GameEvent::E_SET_PHONEMES_FILE, &GameEventData(qPrintable(m_phonemeFileName)), 0)); blockSignals(false); }