Пример #1
0
void SkeletonModel::updateAttitude(const glm::quat& orientation) {
    setTranslation(_owningAvatar->getSkeletonPosition());
    setRotation(orientation * Quaternions::Y_180);
    setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getModelScale());
}
Пример #2
0
void ConstraintsNode::applyConstrainedTranslation(osg::Vec3 v)
{
    osg::Vec3 localPos = this->getTranslation();
    osg::ref_ptr<ReferencedNode> hitNode;
    ReferencedNode *testNode;

    // with really big velocities (or small enclosures), and if the surface
    // doesn't damp the velocity, it's possible to get see an infinite recursion
    // occur. So, we keep a recursionCounter, and stop prevent this occurrence:
    if (++recursionCounter > 10) return;

    /*
    std::cout << std::endl << "checking for collisions" << std::endl;
    std::cout << "start =  " << localPos.x()<<","<<localPos.y()<<","<<localPos.z() << std::endl;
    std::cout << "v =      " << v.x()<<","<<v.y()<<","<<v.z() << std::endl;
    */

    osg::ref_ptr<ReferencedNode> targetNode = dynamic_cast<ReferencedNode*>(_target->s_thing);

    if (targetNode.valid())
    {
        // get current position (including offset from previous bounces)
        osg::Matrix thisMatrix = osg::computeLocalToWorld(this->currentNodePath);
        osg::Vec3 worldPos = thisMatrix.getTrans();

        // set up intersector:
        osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector = new osgUtil::LineSegmentIntersector(worldPos, worldPos + v);
        osgUtil::IntersectionVisitor iv(intersector.get());

        // apply intersector:
        targetNode->accept(iv);

        if (intersector->containsIntersections())
        {
            osgUtil::LineSegmentIntersector::Intersections intersections;
            osgUtil::LineSegmentIntersector::Intersections::iterator itr;

            intersections = intersector->getIntersections();

            for (itr = intersections.begin(); itr != intersections.end(); ++itr)
            {
                //std::cout << "testing intersection with " << (*itr).nodePath[0]->getName() << std::endl;

                // first check if the hit is with our target (should be first in
                // the nodepath):

                testNode = dynamic_cast<ReferencedNode*>((*itr).nodePath[0]);
                if (testNode!=targetNode) continue;

                // The intersection has a nodepath that we have to walk down to
                // see which exact node has been hit. It's possible that there
                // are other SPIN nodes in the targetNode's subgraph that are
                // the real source of intersection:

                hitNode = 0;
                testNode = 0;
                for (unsigned int i=0; i<(*itr).nodePath.size(); i++)
                {
                    testNode = dynamic_cast<ReferencedNode*>((*itr).nodePath[i]);
                    if (testNode) hitNode = testNode;
                }

                if (hitNode.valid())
                {

                    //std::cout << id->s_name << " collision!!! with " << (*itr).drawable->getName() << "[" << (*itr).primitiveIndex << "] @ " << std::endl;
                    //std::cout << "localHitPoint:\t" << localHitPoint.x()<<","<<localHitPoint.y()<<","<<localHitPoint.z() << std::endl;
                    //std::cout << "localHitNormal:\t" << localHitNormal.x()<<","<<localHitNormal.y()<<","<<localHitNormal.z() << std::endl;


                    // For BOUNCE mode, we need to check if we've intersected
                    // with the same primitive again. This may occur since we
                    // do recursive translations after repositioning the node at
                    // the bounce point (and there may be numerical imprecision)
                    // If so, we skip this intersection:
                    if ((_mode==BOUNCE) &&
                            (lastDrawable.get()==(*itr).drawable.get()) &&
                            (lastPrimitiveIndex==(int)(*itr).primitiveIndex))
                    {
                        //std::cout << "... skipping" << std::endl;
                        continue;
                    }
                    else
                    {
                        lastDrawable=(*itr).drawable;
                        lastPrimitiveIndex=(*itr).primitiveIndex;
                    }


                    osg::Vec3 localHitPoint = (*itr).getWorldIntersectPoint();
                    osg::Vec3 localHitNormal = (*itr).getWorldIntersectNormal();
                    localHitNormal.normalize();


                    // current direction vector:
                    osg::Vec3 dirVec = v;
                    dirVec.normalize();

                    // Find the rotation between the direction vector and the
                    // surface normal at the hit point:
                    osg::Quat rot;
                    rot.makeRotate(dirVec, localHitNormal);
                    //std::cout << "rot =     " << rot.x()<<","<<rot.y()<<","<<rot.z()<<","<<rot.w() << " ... angle=" << acos(rot.w())*2 << ", indegrees=" << osg::RadiansToDegrees(acos(rot.w()))*2 << std::endl;

                    // the surface normal may be in the opposite direction
                    // from us. If so, we need to flip it:
                    if (acos(rot.w()) * 2 > osg::PI_2)
                    {
                        localHitNormal *= -1;
                        rot.makeRotate(dirVec, localHitNormal);
                        //std::cout << "flipped = " << rot.x()<<","<<rot.y()<<","<<rot.z()<<","<<rot.w() << " ... angle=" << acos(rot.w())*2 << ", indegrees=" << osg::RadiansToDegrees(acos(rot.w()))*2 << std::endl;
                    }


                    osg::Vec3 rotEulers = QuatToEuler(rot);
                    //std::cout << "newHitNormal:\t" << localHitNormal.x()<<","<<localHitNormal.y()<<","<<localHitNormal.z() << std::endl;


                    if ((_mode==COLLIDE)||(_mode==COLLIDE_THRU)||(_mode==STICK))
                    {
                        // Let the collisionPoint be just a bit before the real
                        // hitpoint (to avoid numerical imprecision placing the
                        // node behind the plane):
                        osg::Vec3 collisionPoint = localHitPoint - (localHitNormal * 0.01);

                        // place the node at the collision point
                        setTranslation(collisionPoint.x(), collisionPoint.y(), collisionPoint.z());

                        BROADCAST(this, "ssfff", "collide", hitNode->id->s_name, osg::RadiansToDegrees(rotEulers.x()), osg::RadiansToDegrees(rotEulers.y()), osg::RadiansToDegrees(rotEulers.z()));


                        if (_mode==COLLIDE)
                        {
                            // SLIDE along the hit plane with the left over energy:
                            // ie, project the remaining vector onto the surface we
                            // just intersected with.
                            //
                            // using:
                            //   cos(theta) = distToSurface / remainderVector length
                            //
                            double cosTheta = (dirVec * -localHitNormal) ; // dot product
                            osg::Vec3 remainderVector = (localPos + v) - localHitPoint;
                            double distToSurface = cosTheta * remainderVector.length();
                            osg::Vec3 slideVector = remainderVector + (localHitNormal * distToSurface);

                            // pseudo-recursively apply remainder of bounce:
                            applyConstrainedTranslation( slideVector );
                        }
                        else if (_mode==COLLIDE_THRU)
                        {
                            // allow the node to pass thru (ie, just apply the
                            // translation):
                            //setTranslation(v.x(), v.y(), v.z());
                            osg::Vec3 newPos = localPos + v;
                            setTranslation(newPos.x(), newPos.y(), newPos.z());
                        }

                        return;
                    }


                    else if (_mode==BOUNCE)
                    {
                        // bounce returns a translation mirrored about the hit
                        // normal to the surface



                        // the new direction vector is a rotated version
                        // of the original, about the localHitNormal:
                        //osg::Vec3 newDir = (rot * 2.0) * -dirVec;
                        osg::Vec3 newDir = (rot * (rot * -dirVec));
                        newDir.normalize();
                        //std::cout << "newDir = " << newDir.x()<<","<<newDir.y()<<","<<newDir.z() << std::endl;


                        // amount of distance still to travel after bounce:
                        double dist = v.length() - (localHitPoint-localPos).length();
                        //std::cout << "dist =   " << dist << std::endl;



                        // in node is translating (ie, changing position
                        // independently from it's orientatino), then we need to
                        // flip the velocity vector.
                        if (_velocityMode == GroupNode::TRANSLATE)
                        {
                            osg::Vec3 newVel = newDir * _velocity.length();
                            setVelocity(newVel.x(), newVel.y(), newVel.z());
                        }

                        // if the node is moving along it's orientation vector,
                        // we need to update the orientation of so that it
                        // points in 'bounced' direction
                        else if (_velocityMode == GroupNode::MOVE)
                        {
                            osg::Quat newQuat;
                            newQuat.makeRotate(osg::Vec3(0,1,0),  newDir);
                            osg::Vec3 newRot = Vec3inDegrees(QuatToEuler(newQuat));
                            //std::cout << "newrot = " << newRot.x()<<","<<newRot.y()<<","<<newRot.z() << std::endl;
                            setOrientation(newRot.x(), newRot.y(), newRot.z());

                        }

                        // the new position will be just a hair before hitpoint
                        // (because numerical imprecision may place the hitpoint
                        // slightly beyond the surface, and when we bounce the
                        // node, we don't want to  intersect with the same
                        // surface again)
                        double HAIR = 0.0000001;
                        setTranslation(localHitPoint.x()-dirVec.x()*HAIR, localHitPoint.y()-dirVec.y()*HAIR, localHitPoint.z()-dirVec.z()*HAIR);
                        //setTranslation(localHitPoint.x(), localHitPoint.y(), localHitPoint.z());

                        //std::cout << "rotEulers = " << osg::RadiansToDegrees(rotEulers.x())<<","<<osg::RadiansToDegrees(rotEulers.y())<<","<<osg::RadiansToDegrees(rotEulers.z()) << std::endl;
                        BROADCAST(this, "ssfff", "bounce", hitNode->id->s_name, osg::RadiansToDegrees(rotEulers.x()), osg::RadiansToDegrees(rotEulers.y()), osg::RadiansToDegrees(rotEulers.z()));

                        // pseudo-recursively apply remainder of bounce:
                        applyConstrainedTranslation(newDir*dist);

                        return;

                    }
                }
            }
        } //else std::cout << "no intersections" << std::endl;
    }


    // no intersections, so just do regular translation:
    osg::Vec3 newPos = localPos + v;
    setTranslation(newPos.x(), newPos.y(), newPos.z());
}
Пример #3
0
void Matrix44F::setTranslation(const Vector3F& p)
{
	setTranslation( p.x, p.y, p.z);
}
Пример #4
0
void TangramPieces::setPos(float px, float py, float pz, glm::quat q){
	setRotation(q);
	setTranslation(px, py, pz);
}
Пример #5
0
void TangramPieces::resetPos(float x, float y, float z, glm::quat q) {
	setTranslation(x, y, z);
	setRotation(q);
}
Пример #6
0
void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
    setTranslation(_owningAvatar->getSkeletonPosition());
    static const glm::quat refOrientation = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
    setRotation(_owningAvatar->getOrientation() * refOrientation);
    setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getScale());
    setBlendshapeCoefficients(_owningAvatar->getHead()->getBlendshapeCoefficients());
    
    Model::simulate(deltaTime, fullUpdate);
    
    if (!isActive() || !_owningAvatar->isMyAvatar()) {
        return; // only simulate for own avatar
    }
    
    MyAvatar* myAvatar = static_cast<MyAvatar*>(_owningAvatar);
    if (myAvatar->isPlaying()) {
        // Don't take inputs if playing back a recording.
        return;
    }

    const FBXGeometry& geometry = _geometry->getFBXGeometry();
    PrioVR* prioVR = Application::getInstance()->getPrioVR();
    if (prioVR->isActive()) {
        for (int i = 0; i < prioVR->getJointRotations().size(); i++) {
            int humanIKJointIndex = prioVR->getHumanIKJointIndices().at(i);
            if (humanIKJointIndex == -1) {
                continue;
            }
            int jointIndex = geometry.humanIKJointIndices.at(humanIKJointIndex);
            if (jointIndex != -1) {
                JointState& state = _jointStates[jointIndex];
                state.setRotationInBindFrame(prioVR->getJointRotations().at(i), PALM_PRIORITY);
            }
        }
        return;
    }

    // find the left and rightmost active palms
    int leftPalmIndex, rightPalmIndex;
    Hand* hand = _owningAvatar->getHand();
    hand->getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex);

    const float HAND_RESTORATION_RATE = 0.25f;    
    if (leftPalmIndex == -1 || rightPalmIndex == -1) {
        // palms are not yet set, use mouse
        if (_owningAvatar->getHandState() == HAND_STATE_NULL) {
            restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
        } else {
            // transform into model-frame
            glm::vec3 handPosition = glm::inverse(_rotation) * (_owningAvatar->getHandPosition() - _translation);
            applyHandPosition(geometry.rightHandJointIndex, handPosition);
        }
        restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);

    } else if (leftPalmIndex == rightPalmIndex) {
        // right hand only
        applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[leftPalmIndex]);
        restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);

    } else {
        applyPalmData(geometry.leftHandJointIndex, hand->getPalms()[leftPalmIndex]);
        applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[rightPalmIndex]);
    }

    _boundingShape.setTranslation(_translation + _rotation * _boundingShapeLocalOffset);
    _boundingShape.setRotation(_rotation);
}
Пример #7
0
//===========================================
// Entity::assignData
//===========================================
void Entity::assignData(const XmlNode data) {
   if (data.isNull() || data.name() != "Entity") return;

   AssetManager assetManager;
   ShapeFactory shapeFactory;

   try {
      bool silent = isSilent();
      setSilent(true);

      XmlAttribute attr = data.firstAttribute();
      if (!attr.isNull() && attr.name() == "type") {
         m_type = internString(attr.getString());
         attr = attr.nextAttribute();
      }

      if (!attr.isNull() && attr.name() == "name") {
         m_name = internString(attr.getString());
         attr = attr.nextAttribute();
      }

      Vec2f transl = m_transl;

      if (!attr.isNull() && attr.name() == "x") {
         transl.x = attr.getFloat();
         attr = attr.nextAttribute();
      }

      if (!attr.isNull() && attr.name() == "y") {
         transl.y = attr.getFloat();
         attr = attr.nextAttribute();
      }

      setTranslation(transl);

      if (!attr.isNull() && attr.name() == "z") {
         m_z = attr.getFloat();

         // So that no Z values are 'exactly' equal
         m_z += 0.1f * static_cast<float32_t>(rand()) / static_cast<float32_t>(RAND_MAX);

         attr = attr.nextAttribute();
      }

      XmlNode node = data.firstChild();
      if (!node.isNull() && node.name() == "shape") {
         m_shape = unique_ptr<Shape>(shapeFactory.create(node.firstChild()));
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "scale") {
         setScale(Vec2f(node.firstChild()));
         node = node.nextSibling();
      }

      if (!attr.isNull() && attr.name() == "rot") {
         setRotation(attr.getFloat());
      }

      if (!node.isNull() && node.name() == "fillColour") {
         m_fillColour = Colour(node.firstChild());
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "lineColour") {
         m_lineColour = Colour(node.firstChild());
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "lineWidth") {
         m_lineWidth = node.getInt();
         node = node.nextSibling();
      }

      if (!node.isNull() && node.name() == "children") {
         XmlNode node_ = node.firstChild();

         while (!node_.isNull() && node_.name() == "child") {
            XmlAttribute attr = node_.firstAttribute();

            if (!attr.isNull() && attr.name() == "ptr") {
               long id = attr.getLong();

               pEntity_t child = boost::dynamic_pointer_cast<Entity>(assetManager.getAssetPointer(id));

               if (!child)
                  throw XmlException("Bad entity asset id", __FILE__, __LINE__);

               addChild(child);
            }

            node_ = node_.nextSibling();
         }
      }

      setSilent(silent);
   }
   catch (XmlException& e) {
      e.prepend("Error parsing XML for instance of class Entity; ");
      throw;
   }

   recomputeBoundary();
}
Пример #8
0
/**
 * @brief      Overloaded setTranslation function.
 * @see        Camera3D::setTranslation( const QVector3D& t )
 *
 * @param[in]  x     The new x-axis location.
 * @param[in]  y     The new y-axis location.
 * @param[in]  z     The new z-axis location.
 */
void Camera3D::setTranslation( float x, float y, float z )
{
    setTranslation( QVector3D( x, y, z ) );
}
Пример #9
0
void SkeletonModel::simulate(float deltaTime, bool fullUpdate) {
    setTranslation(_owningAvatar->getSkeletonPosition());
    static const glm::quat refOrientation = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f));
    setRotation(_owningAvatar->getOrientation() * refOrientation);
    setScale(glm::vec3(1.0f, 1.0f, 1.0f) * _owningAvatar->getScale());
    setBlendshapeCoefficients(_owningAvatar->getHead()->getBlendshapeCoefficients());

    Model::simulate(deltaTime, fullUpdate);
    
    if (!isActive() || !_owningAvatar->isMyAvatar()) {
        return; // only simulate for own avatar
    }
    
    MyAvatar* myAvatar = static_cast<MyAvatar*>(_owningAvatar);
    if (myAvatar->isPlaying()) {
        // Don't take inputs if playing back a recording.
        return;
    }

    const FBXGeometry& geometry = _geometry->getFBXGeometry();

    // find the left and rightmost active palms
    int leftPalmIndex, rightPalmIndex;
    Hand* hand = _owningAvatar->getHand();
    hand->getLeftRightPalmIndices(leftPalmIndex, rightPalmIndex);

    const float HAND_RESTORATION_RATE = 0.25f;
    if (leftPalmIndex == -1 && rightPalmIndex == -1) {
        // palms are not yet set, use mouse
        if (_owningAvatar->getHandState() == HAND_STATE_NULL) {
            restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
        } else {
            // transform into model-frame
            glm::vec3 handPosition = glm::inverse(_rotation) * (_owningAvatar->getHandPosition() - _translation);
            applyHandPosition(geometry.rightHandJointIndex, handPosition);
        }
        restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);

    } else if (leftPalmIndex == rightPalmIndex) {
        // right hand only
        applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[leftPalmIndex]);
        restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);

    } else {
        if (leftPalmIndex != -1) {
            applyPalmData(geometry.leftHandJointIndex, hand->getPalms()[leftPalmIndex]);
        } else {
            restoreLeftHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
        }
        if (rightPalmIndex != -1) {
            applyPalmData(geometry.rightHandJointIndex, hand->getPalms()[rightPalmIndex]);
        } else {
            restoreRightHandPosition(HAND_RESTORATION_RATE, PALM_PRIORITY);
        }
    }

    if (_isFirstPerson) {
        cauterizeHead();
        updateClusterMatrices();
    }

    _boundingShape.setTranslation(_translation + _rotation * _boundingShapeLocalOffset);
    _boundingShape.setRotation(_rotation);
}
Пример #10
0
void gTranslate(GContext *context, const float vector[2])
{
	setTranslation(context, vector[0],vector[1]);
}
Пример #11
0
void Scene::setTranslation(double x, double y, double z) {
  setTranslation(Translation(x, y, z));
}
Пример #12
0
void Transform::setAnimationPropertyValue(int propertyId, AnimationValue* value, float blendWeight)
{
    GP_ASSERT(value);
    GP_ASSERT(blendWeight >= 0.0f && blendWeight <= 1.0f);

    switch (propertyId)
    {
    case ANIMATE_SCALE_UNIT:
    {
        float scale = Curve::lerp(blendWeight, _scale.x, value->getFloat(0));
        setScale(scale);
        break;
    }
    case ANIMATE_SCALE:
    {
        setScale(Curve::lerp(blendWeight, _scale.x, value->getFloat(0)), Curve::lerp(blendWeight, _scale.y, value->getFloat(1)), Curve::lerp(blendWeight, _scale.z, value->getFloat(2)));
        break;
    }
    case ANIMATE_SCALE_X:
    {
        setScaleX(Curve::lerp(blendWeight, _scale.x, value->getFloat(0)));
        break;
    }
    case ANIMATE_SCALE_Y:
    {
        setScaleY(Curve::lerp(blendWeight, _scale.y, value->getFloat(0)));
        break;
    }
    case ANIMATE_SCALE_Z:
    {
        setScaleZ(Curve::lerp(blendWeight, _scale.z, value->getFloat(0)));
        break;
    }
    case ANIMATE_ROTATE:
    {
        applyAnimationValueRotation(value, 0, blendWeight);
        break;
    }
    case ANIMATE_TRANSLATE:
    {
        setTranslation(Curve::lerp(blendWeight, _translation.x, value->getFloat(0)), Curve::lerp(blendWeight, _translation.y, value->getFloat(1)), Curve::lerp(blendWeight, _translation.z, value->getFloat(2)));
        break;
    }
    case ANIMATE_TRANSLATE_X:
    {
        setTranslationX(Curve::lerp(blendWeight, _translation.x, value->getFloat(0)));
        break;
    }
    case ANIMATE_TRANSLATE_Y:
    {
        setTranslationY(Curve::lerp(blendWeight, _translation.y, value->getFloat(0)));
        break;
    }
    case ANIMATE_TRANSLATE_Z:
    {
        setTranslationZ(Curve::lerp(blendWeight, _translation.z, value->getFloat(0)));
        break;
    }
    case ANIMATE_ROTATE_TRANSLATE:
    {
        applyAnimationValueRotation(value, 0, blendWeight);
        setTranslation(Curve::lerp(blendWeight, _translation.x, value->getFloat(4)), Curve::lerp(blendWeight, _translation.y, value->getFloat(5)), Curve::lerp(blendWeight, _translation.z, value->getFloat(6)));
        break;
    }
    case ANIMATE_SCALE_ROTATE:
    {
        setScale(Curve::lerp(blendWeight, _scale.x, value->getFloat(0)), Curve::lerp(blendWeight, _scale.y, value->getFloat(1)), Curve::lerp(blendWeight, _scale.z, value->getFloat(2)));
        applyAnimationValueRotation(value, 3, blendWeight);
        break;
    }
    case ANIMATE_SCALE_TRANSLATE:
    {
        setScale(Curve::lerp(blendWeight, _scale.x, value->getFloat(0)), Curve::lerp(blendWeight, _scale.y, value->getFloat(1)), Curve::lerp(blendWeight, _scale.z, value->getFloat(2)));
        setTranslation(Curve::lerp(blendWeight, _translation.x, value->getFloat(3)), Curve::lerp(blendWeight, _translation.y, value->getFloat(4)), Curve::lerp(blendWeight, _translation.z, value->getFloat(5)));
        break;
    }
    case ANIMATE_SCALE_ROTATE_TRANSLATE:
    {
        setScale(Curve::lerp(blendWeight, _scale.x, value->getFloat(0)), Curve::lerp(blendWeight, _scale.y, value->getFloat(1)), Curve::lerp(blendWeight, _scale.z, value->getFloat(2)));
        applyAnimationValueRotation(value, 3, blendWeight);
        setTranslation(Curve::lerp(blendWeight, _translation.x, value->getFloat(7)), Curve::lerp(blendWeight, _translation.y, value->getFloat(8)), Curve::lerp(blendWeight, _translation.z, value->getFloat(9)));
        break;
    }
    default:
        break;
    }
}
Пример #13
0
	void cEntity::initialize(sVector3 const& pos, float radian, bool isSceneObject, bool isSyncHeight)
	{
		m_isSceneObject = isSceneObject;
		setTranslation(pos, radian, isSyncHeight);
	}
Пример #14
0
void InputMoveComponent::update( float dt )
{
	auto comp = parent->getComponent<TransformComponent>();
	comp->setTranslation( comp->getTranslation() + glm::vec3( 0, (GetAsyncKeyState('W')?1:0) - (GetAsyncKeyState('S')?1:0), (GetAsyncKeyState('D')?1:0) - (GetAsyncKeyState('A')?1:0) )*4.0f*dt  );
}
Пример #15
0
	void MayaCamera::Update(float timestep)
	{
		(void)timestep;

		// Track mouse motion
		int2 mousePos;
		GetCursorPos((POINT *)&mousePos);
		int2 mouseMove = mousePos - m_mousePosPrev;
		m_mousePosPrev = mousePos;

		// Handle mouse rotation
		if (m_mbuttonCur == MBUTTON_Left)
		{
			m_yaw -= m_rotateSpeed * mouseMove.x;
			m_yaw = modPositive(m_yaw, 2.0f*pi);
			
			m_pitch -= m_rotateSpeed * mouseMove.y;
			m_pitch = clamp(m_pitch, -0.5f*pi, 0.5f*pi);
		}

		// Retrieve controller state
		XINPUT_STATE controllerState = {};
		float2 controllerLeftStick(0.0f), controllerRightStick(0.0f);
		float controllerLeftTrigger = 0.0f, controllerRightTrigger = 0.0f;
		if (m_controllerPresent)
		{
			// Look out for disconnection
			if (XInputGetState(0, &controllerState) == ERROR_SUCCESS)
			{
				// Decode axes and apply dead zones

				controllerLeftTrigger = float(max(0, controllerState.Gamepad.bLeftTrigger - XINPUT_GAMEPAD_TRIGGER_THRESHOLD)) / float(255 - XINPUT_GAMEPAD_TRIGGER_THRESHOLD);
				controllerRightTrigger = float(max(0, controllerState.Gamepad.bRightTrigger - XINPUT_GAMEPAD_TRIGGER_THRESHOLD)) / float(255 - XINPUT_GAMEPAD_TRIGGER_THRESHOLD);

				controllerLeftStick = float2(controllerState.Gamepad.sThumbLX, controllerState.Gamepad.sThumbLY);
				float lengthLeft = length(controllerLeftStick);
				if (lengthLeft > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
					controllerLeftStick = (controllerLeftStick / lengthLeft) * (lengthLeft - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) / float(32768 - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
				else
					controllerLeftStick = float2(0.0f);

				controllerRightStick = float2(controllerState.Gamepad.sThumbRX, controllerState.Gamepad.sThumbRY);
				float lengthRight = length(controllerRightStick);
				if (lengthRight > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
					controllerRightStick = (controllerRightStick / lengthRight) * (lengthRight - XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) / float(32768 - XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
				else
					controllerRightStick = float2(0.0f);
			}
			else
			{
				m_controllerPresent = false;
			}
		}

		// Handle controller rotation
		if (m_controllerPresent)
		{
			m_yaw -= m_controllerRotateSpeed * controllerRightStick.x * abs(controllerRightStick.x) * timestep;
			m_yaw = modPositive(m_yaw, 2.0f*pi);

			m_pitch += m_controllerRotateSpeed * controllerRightStick.y * abs(controllerRightStick.y) * timestep;
			m_pitch = clamp(m_pitch, -0.5f*pi, 0.5f*pi);
		}

		UpdateOrientation();

		// Handle zoom
		if (m_mbuttonCur == MBUTTON_Right)
		{
			m_radius *= expf(mouseMove.y * m_zoomSpeed);
		}
		m_radius *= expf(-m_wheelDelta * m_zoomWheelSpeed);
		m_wheelDelta = 0;

		// Handle controller zoom
		if (m_controllerPresent && !(controllerState.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER))
		{
			m_radius *= expf(-controllerLeftStick.y * abs(controllerLeftStick.y) * m_controllerZoomSpeed * timestep);
		}

		// Handle motion of target point
		if (m_mbuttonCur == MBUTTON_Middle)
		{
			m_posTarget -= m_rotateSpeed * mouseMove.x * m_radius * m_viewToWorld[0].xyz;
			m_posTarget += m_rotateSpeed * mouseMove.y * m_radius * m_viewToWorld[1].xyz;
		}

		// Handle controller motion of target point
		if (m_controllerPresent && (controllerState.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER))
		{
			float3 localVelocity(0.0f);
			localVelocity.x = controllerLeftStick.x * abs(controllerLeftStick.x);
			localVelocity.y = square(controllerRightTrigger) - square(controllerLeftTrigger);
			localVelocity.z = -controllerLeftStick.y * abs(controllerLeftStick.y);
			m_posTarget += xfmVector(localVelocity, m_viewToWorld) * (m_radius * m_controllerMoveSpeed * timestep);
		}

		// Calculate remaining matrices
		m_pos = m_posTarget + m_radius * m_viewToWorld[2].xyz;
		setTranslation(&m_viewToWorld, m_pos);
		UpdateWorldToClip();
	}
Пример #16
0
	void FPSCamera::Update(float timestep)
	{
		// Track mouse motion
		int2 mousePos;
		GetCursorPos((POINT *)&mousePos);
		int2 mouseMove = mousePos - m_mousePosPrev;
		m_mousePosPrev = mousePos;

		// Handle mouse rotation
		if (m_mbuttonActivate == MBUTTON_None ||
			m_mbuttonCur == m_mbuttonActivate)
		{
			m_yaw -= m_rotateSpeed * mouseMove.x;
			m_yaw = modPositive(m_yaw, 2.0f*pi);
			
			m_pitch -= m_rotateSpeed * mouseMove.y;
			m_pitch = clamp(m_pitch, -0.5f*pi, 0.5f*pi);
		}

		// Retrieve controller state
		XINPUT_STATE controllerState = {};
		float2 controllerLeftStick(0.0f), controllerRightStick(0.0f);
		float controllerLeftTrigger = 0.0f, controllerRightTrigger = 0.0f;
		if (m_controllerPresent)
		{
			// Look out for disconnection
			if (XInputGetState(0, &controllerState) == ERROR_SUCCESS)
			{
				// Decode axes and apply dead zones

				controllerLeftTrigger = float(max(0, controllerState.Gamepad.bLeftTrigger - XINPUT_GAMEPAD_TRIGGER_THRESHOLD)) / float(255 - XINPUT_GAMEPAD_TRIGGER_THRESHOLD);
				controllerRightTrigger = float(max(0, controllerState.Gamepad.bRightTrigger - XINPUT_GAMEPAD_TRIGGER_THRESHOLD)) / float(255 - XINPUT_GAMEPAD_TRIGGER_THRESHOLD);

				controllerLeftStick = float2(controllerState.Gamepad.sThumbLX, controllerState.Gamepad.sThumbLY);
				float lengthLeft = length(controllerLeftStick);
				if (lengthLeft > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)
					controllerLeftStick = (controllerLeftStick / lengthLeft) * (lengthLeft - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) / float(32768 - XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE);
				else
					controllerLeftStick = float2(0.0f);

				controllerRightStick = float2(controllerState.Gamepad.sThumbRX, controllerState.Gamepad.sThumbRY);
				float lengthRight = length(controllerRightStick);
				if (lengthRight > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
					controllerRightStick = (controllerRightStick / lengthRight) * (lengthRight - XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) / float(32768 - XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE);
				else
					controllerRightStick = float2(0.0f);
			}
			else
			{
				m_controllerPresent = false;
			}
		}

		// Handle controller rotation
		if (m_controllerPresent)
		{
			m_yaw -= m_controllerRotateSpeed * controllerRightStick.x * abs(controllerRightStick.x) * timestep;
			m_yaw = modPositive(m_yaw, 2.0f*pi);

			m_pitch += m_controllerRotateSpeed * controllerRightStick.y * abs(controllerRightStick.y) * timestep;
			m_pitch = clamp(m_pitch, -0.5f*pi, 0.5f*pi);
		}

		UpdateOrientation();

		// Handle translation

		// !!!UNDONE: acceleration based on how long you've been holding the button,
		// to make fine motions easier?
		float moveStep = timestep * m_moveSpeed;

		// !!!UNDONE: move keyboard tracking into an input system that respects focus, etc.
		if (GetAsyncKeyState(VK_SHIFT) || (controllerState.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER))
			moveStep *= 3.0f;

		if (GetAsyncKeyState('W'))
			m_pos -= m_viewToWorld[2].xyz * moveStep;
		if (GetAsyncKeyState('S'))
			m_pos += m_viewToWorld[2].xyz * moveStep;
		if (GetAsyncKeyState('A'))
			m_pos -= m_viewToWorld[0].xyz * moveStep;
		if (GetAsyncKeyState('D'))
			m_pos += m_viewToWorld[0].xyz * moveStep;
		if (GetAsyncKeyState('E'))
			m_pos += m_viewToWorld[1].xyz * moveStep;
		if (GetAsyncKeyState('C'))
			m_pos -= m_viewToWorld[1].xyz * moveStep;

		if (m_controllerPresent)
		{
			float3 localVelocity(0.0f);
			localVelocity.x = controllerLeftStick.x * abs(controllerLeftStick.x);
			localVelocity.y = square(controllerRightTrigger) - square(controllerLeftTrigger);
			localVelocity.z = -controllerLeftStick.y * abs(controllerLeftStick.y);
			m_pos += xfmVector(localVelocity, m_viewToWorld) * (moveStep * m_controllerMoveSpeed);
		}

		// Calculate remaining matrices
		setTranslation(&m_viewToWorld, m_pos);
		UpdateWorldToClip();
	}