void Astrolabe::setRotationTween( string axis, float startVal, float step, float duration, float delay, float increment, float _scale )
{
	addRotationTween( axis, startVal, step, duration, delay, increment, _scale );
};
Esempio n. 2
0
//----------------------------------------
void ofEasyFingerCam::begin(ofRectangle viewport)
{
    glEnable(GL_DEPTH_TEST);
    viewportRect = viewport;
    ofCamera::begin(viewport);
    ofPushMatrix();
    glGetDoublev(GL_PROJECTION_MATRIX, this->matP);
    glGetDoublev(GL_MODELVIEW_MATRIX, this->matM);
    glGetIntegerv(GL_VIEWPORT, this->viewport);
    bool hasTweens = false;
    if(rTweens.size()>0)
    {
        hasTweens = true;
        setAnglesFromOrientation();
        targetXRot = rTweens[0]->x;
        targetYRot = rTweens[0]->y;
        targetZRot = rTweens[0]->z;
        updateRotation();
        if(targetXRot - rotationX <1 && targetXRot - rotationX >-1 &&
           targetYRot - rotationY <1 && targetYRot - rotationY >-1 &&
           targetZRot - rotationZ <1 && targetZRot - rotationZ >-1)
        {
            rTweens.erase(rTweens.begin());
        }
        setAnglesFromOrientation();
    }
    if(sTweens.size()>0)
    {
        hasTweens = true;
        if(abs(sTweens.at(0)->scale - getDistance()) < 10)
        {
            float newvalue = (getDistance()-sTweens.at(0)->scale)*0.05/100;
            setDistance(getDistance()+newvalue);
        }
    }
    if(pTweens.size()>0)
    {
        hasTweens = true;
        if(target.getPosition().distance(pTweens.at(0)->pan) > 1)
        {
            ofVec3f newTranslation;
            newTranslation = pTweens.at(0)->pan - target.getPosition();
            translation = newTranslation/10;
            target.move(translation);
        }
        else
        {
            pTweens.erase(pTweens.begin());
        }
    }
    if(hasTweens)
    {
        currentState = TWEENING;
    }
    else
    {
        currentState = STABLE;
        if(bMouseInputEnabled||bFingerInputEnabled)
        {
            if(!bDistanceSet)
            {
                setDistance(getImagePlaneDistance(viewport), true);
            }
            if (fingers.size() > 0 )
            {
                // it's important to check whether we've already accounted for the mouse
                // just in case you use the camera multiple times in a single frame
                if (lastFrame != ofGetFrameNum())
                {
                    lastFrame = ofGetFrameNum();
                    currentState = STABLE;
                    if (fingers.size() == 1)
                    {
                        if(selectedPlane->axis == AxisPlane::NOAXIS)
                        {
                            currentState = ROTATING;
                            // if there is some smart way to use dt to scale the values drag, we should do it
                            // you can't simply multiply drag etc because the behavior is unstable at high framerates
                            // float dt = ofGetLastFrameTime();
                            ofVec2f mousePosScreen = ofVec3f(fingers[0]->getX()*ofGetWidth() - viewport.width/2 - viewport.x, viewport.height/2 - (fingers[0]->getY()*ofGetHeight() - viewport.y), 0);
                            ofVec2f mouseVelScreen = (mousePosScreen - mousePosScreenPrev).lengthSquared();
                            ofVec3f targetPos =  target.getGlobalPosition();
                            ofVec3f mousePosXYZ = ofVec3f(mousePosScreen.x, mousePosScreen.y, targetPos.z);
                            float sphereRadius = min(viewport.width, viewport.height)/2;
                            float diffSquared = sphereRadius * sphereRadius - (targetPos - mousePosXYZ).lengthSquared();
                            if(diffSquared <= 0)
                            {
                                mousePosXYZ.z = 0;
                            }
                            else
                            {
                                mousePosXYZ.z = sqrtf(diffSquared);
                            }
                            mousePosXYZ.z += targetPos.z;
                            ofVec3f mousePosView = ofMatrix4x4::getInverseOf(target.getGlobalTransformMatrix()) * mousePosXYZ;
                            //calc new rotation velocity
                            ofQuaternion newRotation;
                            if(fingerPressedPrev[0])
                            {
                                newRotation.makeRotate(mousePosViewPrev, mousePosView);
                            }
                            fingerPressedPrev[0] = true;
                            //apply drag towards new velocities
                            rotation.slerp(drag, rotation, newRotation); // TODO: add dt
                            mousePosViewPrev = ofMatrix4x4::getInverseOf(target.getGlobalTransformMatrix()) * mousePosXYZ;
                            // apply transforms if they're big enough
                            // TODO: these should be scaled by dt
                            if(translation.lengthSquared() > epsilonTransform)
                            {
                                // TODO: this isn't quite right, it needs to move wrt the rotation
                                target.move(translation);
                            }
                            if (rotation.asVec3().lengthSquared() > epsilonTransform)
                            {
                                target.rotate(rotation.conj());
                            }
                            if (abs(distanceScaleVelocity - 1.0f) > epsilonTransform)
                            {
                                setDistance(getDistance() * (1.0f + distanceScaleVelocity), false);
                            }
                            mousePosScreenPrev = mousePosScreen;
                            // targetFut.setPosition(target.getPosition());
                        }
                    }
                    if (fingers.size() == 2)
                    {
                        currentState = SCALING;
                        if(zooming)
                        {
                            ofVec2f pointa = ofVec2f(fingers[0]->getX()*ofGetWidth(),fingers[0]->getY()*ofGetHeight());
                            ofVec2f pointb = ofVec2f(fingers[1]->getX()*ofGetWidth(),fingers[1]->getY()*ofGetHeight());
                            float newDistance = pointa.distance(pointb);
                            float newDistanceScaleVelocity = 0.0f;
                            if(prevDistance == 0)
                            {
                                prevDistance = newDistance;
                            }
                            else
                            {
                                newDistanceScaleVelocity = zoomSpeed * ( prevDistance - newDistance) / ofVec2f(0,0).distance(ofVec2f(ofGetHeight(),ofGetWidth()));
                                distanceScaleVelocity = ofLerp(distanceScaleVelocity, newDistanceScaleVelocity, drag);
                                if (abs(distanceScaleVelocity - 1.0f) > epsilonTransform)
                                {
                                    setDistance(getDistance() * (1.0f + distanceScaleVelocity), false);
                                }
                                prevDistance = newDistance;
                            }
                        }
                    }
                    else
                    {
                        prevDistance = 0;
                    }
                    if (fingers.size() == 3)
                    {
                        currentState = POINTING;
                    }
                    if (fingers.size() == 5)
                    {
                        if(selectedPlane->axis == AxisPlane::NOAXIS)
                        {
                            currentState = PANNING;
                            //DECIDE LATER
                        }
                    }
                    if (fingers.size() == 10)
                    {
                        if(selectedPlane->axis == AxisPlane::NOAXIS)
                        {
                            currentState = RESET;
                            addPanningTween(ofVec3f(0,0,0));
                            addRotationTween(0, 0, 0, 1);
                        }
                    }
                }
            }
            else
            {
                //MOUSE
                fingerPressedPrev[0] = false;
                // it's important to check whether we've already accounted for the mouse
                // just in case you use the camera multiple times in a single frame
                if (lastFrame != ofGetFrameNum())
                {
                    lastFrame = ofGetFrameNum();
                    if(selectedPlane->axis == AxisPlane::NOAXIS)
                    {
                        // if there is some smart way to use dt to scale the values drag, we should do it
                        // you can't simply multiply drag etc because the behavior is unstable at high framerates
                        // float dt = ofGetLastFrameTime();
                        currentState = STABLE;
                        ofVec2f mousePosScreen = ofVec3f(ofGetMouseX() - viewport.width/2 - viewport.x, viewport.height/2 - (ofGetMouseY() - viewport.y), 0);
                        ofVec2f mouseVelScreen = (mousePosScreen - mousePosScreenPrev).lengthSquared();
                        ofVec3f targetPos =  target.getGlobalPosition();
                        ofVec3f mousePosXYZ = ofVec3f(mousePosScreen.x, mousePosScreen.y, targetPos.z);
                        float sphereRadius = min(viewport.width, viewport.height)/2;
                        float diffSquared = sphereRadius * sphereRadius - (targetPos - mousePosXYZ).lengthSquared();
                        if(diffSquared <= 0)
                        {
                            mousePosXYZ.z = 0;
                        }
                        else
                        {
                            mousePosXYZ.z = sqrtf(diffSquared);
                        }
                        mousePosXYZ.z += targetPos.z;
                        ofVec3f mousePosView = ofMatrix4x4::getInverseOf(target.getGlobalTransformMatrix()) * mousePosXYZ;
                        bool mousePressedCur[] = {ofGetMousePressed(0), ofGetMousePressed(2)};
                        //calc new rotation velocity
                        ofQuaternion newRotation;
                        if(mousePressedPrev[0] && mousePressedCur[0])
                        {
                            newRotation.makeRotate(mousePosViewPrev, mousePosView);
                        }
                        //calc new scale velocity
                        float newDistanceScaleVelocity = 0.0f;
                        if(mousePressedPrev[1] && mousePressedCur[1])
                        {
                            newDistanceScaleVelocity = zoomSpeed * (mousePosScreenPrev.y - mousePosScreen.y) / viewport.height;
                        }
                        mousePressedPrev[0] = mousePressedCur[0];
                        mousePressedPrev[1] = mousePressedCur[1];
                        ofVec3f newTranslation;
                        // TODO: this doesn't work at all. why not?
                        if(ofGetMousePressed() && ofGetKeyPressed(OF_KEY_SHIFT))
                        {
                            newTranslation = mousePosScreenPrev - mousePosScreen;
                        }
                        //apply drag towards new velocities
                        distanceScaleVelocity = ofLerp(distanceScaleVelocity, newDistanceScaleVelocity, drag); // TODO: add dt
                        rotation.slerp(drag, rotation, newRotation); // TODO: add dt
                        translation.interpolate(newTranslation, drag);
                        mousePosViewPrev = ofMatrix4x4::getInverseOf(target.getGlobalTransformMatrix()) * mousePosXYZ;
                        // apply transforms if they're big enough
                        // TODO: these should be scaled by dt
                        if(translation.lengthSquared() > epsilonTransform)
                        {
                            // TODO: this isn't quite right, it needs to move wrt the rotation
                            target.move(translation);
                        }
                        if (rotation.asVec3().lengthSquared() > epsilonTransform)
                        {
                            target.rotate(rotation.conj());
                        }
                        if (abs(distanceScaleVelocity - 1.0f) > epsilonTransform)
                        {
                            setDistance(getDistance() * (1.0f + distanceScaleVelocity), false);
                        }
                        mousePosScreenPrev = mousePosScreen;
                        //targetFut.setPosition(target.getPosition());
                    }
                }
            }
        }
        setAnglesFromOrientation();
    }
    ofCamera::begin(viewport);
}