2

我是 3d 编程的新手,所以就到这里。我正在尝试模拟一个房间。我没有加载墙壁的图像,但我想在代码中模拟边界。请问我该怎么做?

下面是处理相机移动的代码

bool calcMovement()
{
    // return if less then two events have been added.
    if (_ga_t0.get()==NULL || _ga_t1.get()==NULL) return false;

    //calcIntersect();

    double dt = _ga_t0->getTime()-_ga_t1->getTime();

    if (dt<0.0f)
    {
        OSG_INFO << "warning dt = "<<dt<< std::endl;
        dt = 0.0;
    }

    double accelerationFactor = _height*10.0;

    switch(_speedMode)
    {
        case(USE_MOUSE_Y_FOR_SPEED):
        {
            double dy = _ga_t0->getYnormalized();
            _velocity = _height*dy;
            break;
        }
        case(USE_MOUSE_BUTTONS_FOR_SPEED):
        {
            unsigned int buttonMask = _ga_t1->getButtonMask();
            //add cases here for finding which key was pressed. 
            if (buttonMask==GUIEventAdapter::LEFT_MOUSE_BUTTON || wPressed)
            {
                // pan model.

                _velocity += dt*accelerationFactor;

            }
            else if (buttonMask==GUIEventAdapter::MIDDLE_MOUSE_BUTTON ||
                buttonMask==(GUIEventAdapter::LEFT_MOUSE_BUTTON|GUIEventAdapter::RIGHT_MOUSE_BUTTON))
            {

                _velocity = 0.0;

            }
            else if (buttonMask==GUIEventAdapter::RIGHT_MOUSE_BUTTON || sPressed)
            {

                _velocity -= dt*accelerationFactor;

            }
            break;
        }
    }

    osg::CoordinateFrame cf=getCoordinateFrame(_eye);

    osg::Matrixd rotation_matrix;
    rotation_matrix.makeRotate(_rotation);

    osg::Vec3d up = osg::Vec3d(0.0,1.0,0.0) * rotation_matrix;
    osg::Vec3d lv = osg::Vec3d(0.0,0.0,-1.0) * rotation_matrix;
    osg::Vec3d sv = osg::Vec3d(1.0,0.0,0.0) * rotation_matrix;

    // rotate the camera.
    double dx = _ga_t0->getXnormalized();

    double yaw = -inDegrees(dx*50.0*dt);


#ifdef KEYBOARD_PITCH
    double pitch_delta = 0.5;
    if (_pitchUpKeyPressed) _pitch += pitch_delta*dt;
    if (_pitchDownKeyPressed) _pitch -= pitch_delta*dt;
#endif

#if defined(ABOSULTE_PITCH)
    // absolute pitch
    double dy = _ga_t0->getYnormalized();
    _pitch = -dy*0.5;
#elif defined(INCREMENTAL_PITCH)
    // incremental pitch
    double dy = _ga_t0->getYnormalized();
    _pitch += dy*dt;
#endif

    osg::Quat yaw_rotation;
    yaw_rotation.makeRotate(yaw,up);

    _rotation *= yaw_rotation;

    rotation_matrix.makeRotate(_rotation);

    sv = osg::Vec3d(1.0,0.0,0.0) * rotation_matrix;

    wPressed = false;
    sPressed = false;

    // movement is big enough the move the eye point along the look vector.
    if (fabs(_velocity*dt)>1e-8)
    {
        double distanceToMove = _velocity*dt;

        double signedBuffer;
        if (distanceToMove>=0.0) signedBuffer=_buffer;
        else signedBuffer=-_buffer;

        // check to see if any obstruction in front.
        osg::Vec3d ip, np;
        if (intersect(_eye,_eye+lv*(signedBuffer+distanceToMove), ip, np))
        {
            if (distanceToMove>=0.0)
            {
                distanceToMove = (ip-_eye).length()-_buffer;
            }
            else
            {
                distanceToMove = _buffer-(ip-_eye).length();
            }

            _velocity = 0.0;
        }

        // check to see if forward point is correct height above terrain.
        osg::Vec3d fp = _eye + lv*distanceToMove;
        osg::Vec3d lfp = fp - up*(_height*5.0);

        if (intersect(fp, lfp, ip, np))
        {
            if (up*np>0.0) up = np;
            else up = -np;

            _eye = ip+up*_height;

            lv = up^sv;

            computePosition(_eye,_eye+lv,up);

            return true;

        }

        // no hit on the terrain found therefore resort to a fall under
        // under the influence of gravity.
        osg::Vec3d dp = lfp;
        dp -= getUpVector(cf)* (2.0*_modelScale);

        if (intersect(lfp, dp, ip, np))
        {

            if (up*np>0.0) up = np;
            else up = -np;

            _eye = ip+up*_height;

            lv = up^sv;

            computePosition(_eye,_eye+lv,up);

            return true;
        }

        // no collision with terrain has been found therefore track horizontally.

        lv *= (_velocity*dt);

        _eye += lv;
    }

    return true;
}
4

0 回答 0