void OceanLevel::callDebug() { BulletObject* objArt = level().physObjects[_artifactIndex]; objArt->body()->setLinearVelocity(btVector3(0,0,0)); objArt->body()->setAngularVelocity(btVector3(0,0,0)); objArt->body()->setWorldTransform(BulletObject::toBtTransform( mat4::Translation(levelSystem().controller().controllerInfo().leftHand->matrix().translation() + vec3(0,0,-0.2)))); }
void LevelSystem::update(float time) { if(_levelStrategy[_curLevel]) _levelStrategy[_curLevel]->update(time); auto it=_allPortalTaversableObj.begin(); while(it != _allPortalTaversableObj.end()) { PortalTraversableObject& x = *it; switch(x.state) { case PortalTraversableObject::NEW: { mat4 offset; auto scene_portal = _portalsHelper->closestPortal(x.instIn->volume(), offset); if(scene_portal.second && std::find(x.forbiddenPortals.begin(), x.forbiddenPortals.end(), scene_portal.second) != x.forbiddenPortals.end()) { #warning CHANGE_FORBIDEN_PORTAL_REACTION vec3 v = x.instIn->volume().center() - scene_portal.second->volume().center(); v.z() = 0; v.resize(5); x.physObj->body()->applyCentralForce(btVector3(v.x(), v.y(), v.z())); break; } if(scene_portal.first) { x.state = PortalTraversableObject::ENGAGED_IN; x.instOut = &scene_portal.first->scene.add<interface::MeshInstance>(x.instIn->mesh(), offset * x.instIn->matrix()); x.sceneOut = scene_portal.first; x.offset = x.inv_offset = offset; x.inv_offset.invert(); x.portal = scene_portal.second; } } x.lastPos = x.instIn->volume().center(); break; case PortalTraversableObject::ENGAGED_IN: { int crossed = _portalsHelper->hasCrossedPortal(x.instIn->volume().center(), x.lastPos, x.portal, std::max(x.instIn->volume().radius(), 0.1f)); if(crossed == -1) { x.sceneOut->scene.remove(*x.instOut); x.sceneOut = nullptr; x.instOut = nullptr; x.portal = nullptr; x.state = PortalTraversableObject::NEW; } else if(crossed == 0) { x.instOut->setMatrix(x.offset*x.instIn->matrix()); } else { SceneMotionState<interface::MeshInstance>* mt = dynamic_cast<SceneMotionState<interface::MeshInstance>*>(x.physObj->body()->getMotionState()); if(mt) mt->setSceneObject(*x.instOut); x.physObj->setMotionState(nullptr); BulletObject* old = x.physObj; x.physObj = new BulletObject(mt, old->body()->getCollisionShape(), 1.f / old->body()->getInvMass()); x.physObj->body()->setFriction(old->body()->getFriction()); x.physObj->body()->setRestitution(old->body()->getRestitution()); x.physObj->body()->setRollingFriction(old->body()->getRollingFriction()); x.physObj->body()->setCcdMotionThreshold(old->body()->getCcdMotionThreshold()); x.physObj->body()->setCcdSweptSphereRadius(old->body()->getCcdSweptSphereRadius()); vec3 v(old->body()->getLinearVelocity().getX(), old->body()->getLinearVelocity().getY(), old->body()->getLinearVelocity().getZ()); v = x.offset.to<3>() * v; x.physObj->body()->setLinearVelocity(btVector3(v.x(), v.y(), v.z())); v = vec3(old->body()->getAngularVelocity().getX(), old->body()->getAngularVelocity().getY(), old->body()->getAngularVelocity().getZ()); v = x.offset.to<3>() * v; x.physObj->body()->setAngularVelocity(btVector3(v.x(), v.y(), v.z())); x.physObj->body()->setUserIndex(old->body()->getUserIndex()); delete old; _physEngine.addObject(x.physObj, getLevelIndex(x.sceneOut), old->colMask(), old->colWithMask()); x.state = PortalTraversableObject::ENGAGED_OUT; if(x.indexObject >= 0) { getLevel(_curLevel).physObjects[x.indexObject] = x.physObj; getLevel(_curLevel).objects[x.indexObject].meshInstance = x.instOut; } } } x.lastPos = x.instIn->volume().center(); break; case PortalTraversableObject::ENGAGED_OUT: { x.instIn->setMatrix(x.inv_offset*x.instOut->matrix()); int crossed = _portalsHelper->hasCrossedPortal(x.instIn->volume().center(), x.lastPos, x.portal, std::max(x.instIn->volume().radius(), 0.1f)); if(crossed == -1) // remove from current world { getLevel(_curLevel).levelScene->scene.remove(*x.instIn); x.instIn = nullptr; x.state = PortalTraversableObject::OUT; } else if(crossed == 0) { x.lastPos = x.instIn->volume().center(); } else { SceneMotionState<interface::MeshInstance>* mt = dynamic_cast<SceneMotionState<interface::MeshInstance>*>(x.physObj->body()->getMotionState()); if(mt) mt->setSceneObject(*x.instIn); x.physObj->setMotionState(nullptr); BulletObject* old = x.physObj; x.physObj = new BulletObject(mt, old->body()->getCollisionShape(), 1.f / old->body()->getInvMass()); x.physObj->body()->setFriction(old->body()->getFriction()); x.physObj->body()->setRestitution(old->body()->getRestitution()); x.physObj->body()->setRollingFriction(old->body()->getRollingFriction()); x.physObj->body()->setCcdMotionThreshold(old->body()->getCcdMotionThreshold()); x.physObj->body()->setCcdSweptSphereRadius(old->body()->getCcdSweptSphereRadius()); vec3 v(old->body()->getLinearVelocity().getX(), old->body()->getLinearVelocity().getY(), old->body()->getLinearVelocity().getZ()); v = x.inv_offset.to<3>() * v; x.physObj->body()->setLinearVelocity(btVector3(v.x(), v.y(), v.z())); v = vec3(old->body()->getAngularVelocity().getX(), old->body()->getAngularVelocity().getY(), old->body()->getAngularVelocity().getZ()); v = x.inv_offset.to<3>() * v; x.physObj->body()->setAngularVelocity(btVector3(v.x(), v.y(), v.z())); x.physObj->body()->setUserIndex(old->body()->getUserIndex()); delete old; _physEngine.addObject(x.physObj, getLevel(_curLevel).indexScene, old->colMask(), old->colWithMask()); x.state = PortalTraversableObject::ENGAGED_IN; x.lastPos = x.instIn->volume().center(); if(x.indexObject >= 0) { getLevel(_curLevel).physObjects[x.indexObject] = x.physObj; getLevel(_curLevel).objects[x.indexObject].meshInstance = x.instIn; } } }break; case PortalTraversableObject::OUT: { vec3 v = x.inv_offset * x.instOut->volume().center(); float distOut = std::max(DIST_OUT, x.instOut->volume().radius()); if((v-x.portal->volume().center()).length2() > distOut*distOut) { if(x.sceneOut == getLevel(_curLevel).levelScene) { x.state = PortalTraversableObject::NEW; x.instIn = x.instOut; x.instOut = nullptr; x.sceneOut = nullptr; x.portal = nullptr; } else { _inacessiblePortalTaversableObj.push_back(x); _allPortalTaversableObj.erase(it++); continue; } } else { int crossed = _portalsHelper->hasCrossedPortal(v,v, x.portal, std::max(x.instOut->volume().radius(), 0.1f)); if(crossed == 0) // now close enough { x.instIn = &getLevel(_curLevel).levelScene->scene.add<interface::MeshInstance>(x.instOut->mesh(), x.inv_offset * x.instOut->matrix()); x.state = PortalTraversableObject::ENGAGED_OUT; } } x.lastPos = v; }break; } ++it; } }
void OceanLevel::update(float time) { vec3 artifactPos = level().objects[_artifactIndex].meshInstance->matrix().translation(); bool onSlot = false; for(SlotArtifact& slot : _slots) { if((slot.inst->matrix().translation() - artifactPos).length() < 0.02) { onSlot = true; slot.timeOn += time; if(slot.timeOn > TIME_ON_SLOT && slot.resetActive == false) { slot.resetActive = true; if(slot.resetButtonIndex >= 0) { interface::Mesh m = level().objects[slot.resetButtonIndex].meshInstance->mesh(); m.element(0).setEmissive(0.7); level().objects[slot.resetButtonIndex].meshInstance->setMesh(m); } if(slot.portal) setEnablePortal(true, slot.portal); Source* src = levelSystem().listener().addSource(_warpSound); src->setPosition(slot.inst->matrix().translation()); src->play(); src->release(); } } else { slot.timeOn = 0; } if(slot.resetActive && slot.resetButtonIndex >= 0) { if(collidePaddles(level().physObjects[slot.resetButtonIndex])) { if(!slot.onReset) { slot.onReset = true; BulletObject* objArt = level().physObjects[_artifactIndex]; objArt->body()->setLinearVelocity(btVector3(0,0,0)); objArt->body()->setAngularVelocity(btVector3(0,0,0)); objArt->body()->setWorldTransform(BulletObject::toBtTransform(slot.inst->matrix())); if(_timerButtonSound > 0.3) { Source* src = levelSystem().listener().addSource(_buttonSound); src->setPosition(level().objects[slot.resetButtonIndex].meshInstance->matrix().translation()); src->play(); src->release(); _timerButtonSound = 0; } } } else slot.onReset = false; } if(slot.name == "slotArtifact6" && slot.timeOn > TIME_ON_SLOT && _levelState == 0) { int indexBoat = indexObject("boat"); if((level().objects[indexBoat].meshInstance->matrix().translation() - levelSystem().headPosition()).length() < 1) { _timeOnBoat += time; if(_timeOnBoat > 2) { _levelState = 1; _distanceBoat = 0; } } } } manageBoat(time); _timerButtonSound += time; if(onSlot) _timeOnSlot += time; else _timeOnSlot -= time; _timeOnSlot = std::min(std::max(_timeOnSlot, 0.f), TIME_ON_SLOT); interface::Mesh m = level().objects[_artifactIndex].meshInstance->mesh(); for(size_t i=0 ; i<m.nbElements() ; ++i) m.element(i).setEmissive(0.9f * _timeOnSlot / TIME_ON_SLOT); level().objects[_artifactIndex].meshInstance->setMesh(m); }