コード例 #1
0
ファイル: GridModel.cpp プロジェクト: conanhung/sofa_rc1
void GridModel::draw(const core::visual::VisualParams* vparams)
{
    if (!isActive() || !((getNext()==NULL)?vparams->displayFlags().getShowCollisionModels():vparams->displayFlags().getShowBoundingCollisionModels())) return;
    glDisable(GL_LIGHTING);
    int level=0;
    CollisionModel* m = getPrevious();
    float color = 1.0f;
    while (m!=NULL)
    {
        m = m->getPrevious();
        ++level;
        color *= 0.5f;
    }
    if (isSimulated())
        glColor4f(1.0f, 1.0f, 1.0f, color);
    else
        glColor4f(1.0f, 1.0f, 0.0f, color);
    if (color < 1.0f)
    {
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glDepthMask(0);
    }
    for (int i=0;i<size;i++)
    {
        draw(vparams,i);
    }
    if (color < 1.0f)
    {
        glDisable(GL_BLEND);
        glDepthMask(1);
    }
    if (getPrevious()!=NULL)
        getPrevious()->draw(vparams);
}
コード例 #2
0
void CubeModel::draw(const core::visual::VisualParams* vparams)
{
    if (!isActive() || !((getNext()==NULL)?vparams->displayFlags().getShowCollisionModels():vparams->displayFlags().getShowBoundingCollisionModels())) return;

    int level=0;
    CollisionModel* m = getPrevious();
    float color = 1.0f;
    while (m!=NULL)
    {
        m = m->getPrevious();
        ++level;
        color *= 0.5f;
    }
    Vec<4,float> c;
    if (isSimulated())
        c=Vec<4,float>(1.0f, 1.0f, 1.0f, color);
    else
        c=Vec<4,float>(1.0f, 1.0f, 1.0f, color);

    std::vector< Vector3 > points;
    for (int i=0; i<size; i++)
    {
        const Vector3& vmin = elems[i].minBBox;
        const Vector3& vmax = elems[i].maxBBox;

        points.push_back(Vector3(vmin[0], vmin[1], vmin[2]));
        points.push_back(Vector3(vmin[0], vmin[1], vmax[2]));
        points.push_back(Vector3(vmin[0], vmax[1], vmin[2]));
        points.push_back(Vector3(vmin[0], vmax[1], vmax[2]));
        points.push_back(Vector3(vmax[0], vmin[1], vmin[2]));
        points.push_back(Vector3(vmax[0], vmin[1], vmax[2]));
        points.push_back(Vector3(vmax[0], vmax[1], vmin[2]));
        points.push_back(Vector3(vmax[0], vmax[1], vmax[2]));

        points.push_back(Vector3(vmin[0], vmin[1], vmin[2]));
        points.push_back(Vector3(vmin[0], vmax[1], vmin[2]));
        points.push_back(Vector3(vmin[0], vmin[1], vmax[2]));
        points.push_back(Vector3(vmin[0], vmax[1], vmax[2]));
        points.push_back(Vector3(vmax[0], vmin[1], vmin[2]));
        points.push_back(Vector3(vmax[0], vmax[1], vmin[2]));
        points.push_back(Vector3(vmax[0], vmin[1], vmax[2]));
        points.push_back(Vector3(vmax[0], vmax[1], vmax[2]));

        points.push_back(Vector3(vmin[0], vmin[1], vmin[2]));
        points.push_back(Vector3(vmax[0], vmin[1], vmin[2]));
        points.push_back(Vector3(vmin[0], vmax[1], vmin[2]));
        points.push_back(Vector3(vmax[0], vmax[1], vmin[2]));
        points.push_back(Vector3(vmin[0], vmin[1], vmax[2]));
        points.push_back(Vector3(vmax[0], vmin[1], vmax[2]));
        points.push_back(Vector3(vmin[0], vmax[1], vmax[2]));
        points.push_back(Vector3(vmax[0], vmax[1], vmax[2]));
    }

    vparams->drawTool()->drawLines(points, 1, Vec<4,float>(c));


    if (getPrevious()!=NULL)
        getPrevious()->draw(vparams);
}
コード例 #3
0
Vector3f SlideMove(
		const Vector3f & footPos,
		const float eyeHeight,
		const Vector3f & moveDirection,
		const float moveDistance,
		const CollisionModel & collisionModel,
		const CollisionModel & groundCollisionModel
	    )
{
	// Check for collisions at eye level to prevent slipping under walls.
	Vector3f eyePos = footPos + UpVector * eyeHeight;

	// Pop out of any collision models.
	collisionModel.PopOut( eyePos );

	{
		Planef fowardCollisionPlane;
		float forwardDistance = moveDistance;
		if ( !collisionModel.TestRay( eyePos, moveDirection, forwardDistance, &fowardCollisionPlane ) )
		{
			// No collision, move the full distance.
			eyePos += moveDirection * moveDistance;
		}
		else
		{
			// Move up to the point of collision.
			eyePos += moveDirection * forwardDistance;

			// Project the remaining movement onto the collision plane.
			const float COLLISION_BOUNCE = 0.001f;	// don't creep into the plane due to floating-point rounding
			const float intoPlane = moveDirection.Dot( fowardCollisionPlane.N ) - COLLISION_BOUNCE;
			const Vector3f slideDirection = ( moveDirection - fowardCollisionPlane.N * intoPlane );

			// Try to finish the move by sliding along the collision plane.
			float slideDistance = moveDistance;
			collisionModel.TestRay( eyePos - UpVector * RailHeight, slideDirection, slideDistance, NULL );

			eyePos += slideDirection * slideDistance;
		}
	}

	if ( groundCollisionModel.Polytopes.GetSizeI() != 0 )
	{
		// Check for collisions at foot level, which allows following terrain.
		float downDistance = 10.0f;
		groundCollisionModel.TestRay( eyePos, - UpVector, downDistance, NULL );

		// Maintain the minimum camera height.
		if ( eyeHeight - downDistance < 1.0f )
		{
			eyePos += UpVector * ( eyeHeight - downDistance );
		}
	}

	return eyePos - UpVector * eyeHeight;
}
コード例 #4
0
std::pair<bool, Real>
doPicking(const Ogre::Ray& localRay, const CollisionModel& collisionModel, CullingMode cullingMode)
{
    // Convert our ray to Opcode ray
    IceMaths::Ray world_ray(
        IceMaths::Point(localRay.getOrigin().x, localRay.getOrigin().y, localRay.getOrigin().z),
        IceMaths::Point(localRay.getDirection().x, localRay.getDirection().y, localRay.getDirection().z));

    // Be aware we store triangle as ccw in collision mode, and Opcode treat it as cw,
    // so need to inverse cull mode here.
    Opcode::CullMode cullMode;
    switch (cullingMode)
    {
    default:
    case CULL_NONE:
        cullMode = Opcode::CULLMODE_NONE;
        break;
    case CULL_CLOCKWISE:
        cullMode = Opcode::CULLMODE_CCW;
        break;
    case CULL_ANTICLOCKWISE:
        cullMode = Opcode::CULLMODE_CW;
        break;
    }

    // Cull mode callback for Opcode
    struct Local
    {
        static Opcode::CullMode cullModeCallback(udword triangle_index, void* user_data)
        {
            return (Opcode::CullMode) (int) user_data;
        }
    };

    std::pair<bool, Real> ret;

    // Do picking
    Opcode::CollisionFace picked_face;
    ret.first = Opcode::Picking(picked_face,
        world_ray, collisionModel.getOpcodeModel(), 0,
        0, FLT_MAX,
        world_ray.mOrig,
        &Local::cullModeCallback, (void*) (int) cullMode);
    ret.second = ret.first ? picked_face.mDistance : 0;

    return ret;
}
コード例 #5
0
std::pair<bool, Real>
rayCollide(const Ogre::Ray& ray,
           Ogre::MovableObject* movable,
           bool accurate,
           CullingMode cullingMode,
           bool allowAnimable)
{
    // Get local space axis aligned bounding box
    const Ogre::AxisAlignedBox& aabb = movable->getBoundingBox();

    // Matrix4 to transform local space to world space
    const Ogre::Matrix4& localToWorld = movable->_getParentNodeFullTransform();

    // Matrix4 to transform world space to local space
    Ogre::Matrix4 worldToLocal = localToWorld.inverse();

    // Matrix3 to transform world space normal to local space
    Ogre::Matrix3 worldToLocalN;
    worldToLocal.extract3x3Matrix(worldToLocalN);

    // Convert world space ray to local space ray
    // Note:
    //      By preserving the scale between world space and local space of the
    //      direction, we don't need to recalculate the distance later.
    Ogre::Ray localRay;
    localRay.setOrigin(worldToLocal * ray.getOrigin());
    localRay.setDirection(worldToLocalN * ray.getDirection());

    // Intersect with axis aligned bounding box, but because we transformed
    // ray to local space of the bounding box, so this test just like test
    // with oriented bounding box.
    std::pair<bool, Real> ret = localRay.intersects(aabb);

    // Do accurate test if hitted bounding box and user required.
    if (ret.first && accurate)
    {
        if (movable->getMovableType() == Ogre::EntityFactory::FACTORY_TYPE_NAME ||
            allowAnimable && movable->getMovableType() == Ogre::AutoAnimationEntityFactory::FACTORY_TYPE_NAME)
        {
            Ogre::Entity* entity = static_cast<Ogre::Entity*>(movable);
            if (!entity->_isAnimated())
            {
                // Static entity

                // Get the entity mesh
                const Ogre::MeshPtr& mesh = entity->getMesh();

                // Get the collision mode
                CollisionModelPtr collisionModel = CollisionModelManager::getSingleton().getCollisionModel(mesh);

                ret = doPicking(localRay, *collisionModel, cullingMode);
            }
            else if (allowAnimable)
            {
                // Animation entity

                bool addedSoftwareAnimation = false;
                if (entity->getSoftwareAnimationRequests() <= 0)
                {
                    entity->addSoftwareAnimationRequest(false);
                    entity->_updateAnimation();
                    addedSoftwareAnimation = true;
                }

                CollisionModel collisionModel;
                collisionModel.addEntity(entity);
                collisionModel.build(true);

                ret = doPicking(localRay, collisionModel, cullingMode);

                if (addedSoftwareAnimation)
                {
                    entity->removeSoftwareAnimationRequest(false);
                }
            }
        }
    }

    return ret;
}