Пример #1
0
 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))));
 }
Пример #2
0
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;
    }
}
Пример #3
0
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);
}