//------------------------------------------------------------------------------
void SegmentedDynamicLightManager::LightData::setBounds(const AxisAlignedBox& i_Bounds)
{
	mMinX = i_Bounds.getMinimum().x;
	mMaxX = i_Bounds.getMaximum().x;
	mMinZ = i_Bounds.getMinimum().z;
	mMaxZ = i_Bounds.getMaximum().z;
}
    //-------------------------------------------------------------------------
    TerrainTile * OverhangTerrainPage::getTerrainTile( const Vector3 & pt )
    {
        /* Since we don't know if the terrain is square, or has holes, we use a line trace
        to find the containing tile...
        */

        TerrainTile * tile = tiles[ 0 ][ 0 ];

        while ( tile != 0 )
        {
            AxisAlignedBox b = tile -> getBoundingBox();

            if ( pt.x < b.getMinimum().x )
                tile = tile -> _getNeighbor( TerrainTile::WEST );
            else if ( pt.x > b.getMaximum().x )
                tile = tile -> _getNeighbor( TerrainTile::EAST );
            else if ( pt.z < b.getMinimum().z )
                tile = tile -> _getNeighbor( TerrainTile::NORTH );
            else if ( pt.z > b.getMaximum().z )
                tile = tile -> _getNeighbor( TerrainTile::SOUTH );
            else
                return tile;
        }

        return 0;
    }
Пример #3
0
/** Returns true is the box will fit in a child.
*/
bool Octree::_isTwiceSize( const AxisAlignedBox &box ) const
{
    return ( ( box.getMaximum().x - box.getMinimum().x ) <= ( mBox.getMaximum().x - mBox.getMinimum().x ) / 2 ) &&
           ( ( box.getMaximum().y - box.getMinimum().y ) <= ( mBox.getMaximum().y - mBox.getMinimum().y ) / 2 ) &&
           ( ( box.getMaximum().z - box.getMinimum().z ) <= ( mBox.getMaximum().z - mBox.getMinimum().z ) / 2 ) ;

}
Пример #4
0
    // ------------------------------------------------------------------------
    static bool isBoundOkForMcGuire(const AxisAlignedBox& lightCapBounds, const Ogre::Vector3& lightPosition)
    {
        // If light position is inside light cap bound then extrusion could be in opposite directions
        // and McGuire cap could intersect near clip plane of camera frustum without being noticed
        if(lightCapBounds.contains(lightPosition))
            return false;

        // If angular size of object is too high then extrusion could be in almost opposite directions,
        // interpolated points would be extruded by shorter distance, and strange geometry of McGuire cap
        // could be visible even for well tesselated meshes. As a heuristic we will avoid McGuire cap if
        // angular size is larger than 60 degrees - it guarantees that interpolated points would be
        // extruded by at least cos(60deg/2) ~ 86% of the original extrusion distance.
        if(lightCapBounds.getHalfSize().length() / (lightCapBounds.getCenter() - lightPosition).length() > 0.5) // if boundingSphereAngularSize > 60deg
        {
            // Calculate angular size one more time using edge corners angular distance comparision,
            // Determine lit sides of the bound, store in mask
            enum { L = 1, R = 2, B = 4, T = 8, F = 16, N = 32 }; // left, right, bottom, top, far, near
            unsigned lightSidesMask = 
                (lightPosition.x < lightCapBounds.getMinimum().x ? L : 0) | // left
                (lightPosition.x > lightCapBounds.getMaximum().x ? R : 0) | // right
                (lightPosition.y < lightCapBounds.getMinimum().y ? B : 0) | // bottom
                (lightPosition.y > lightCapBounds.getMaximum().y ? T : 0) | // top
                (lightPosition.z < lightCapBounds.getMinimum().z ? F : 0) | // far
                (lightPosition.z > lightCapBounds.getMaximum().z ? N : 0);  // near
            
            // find corners on lit/unlit edge (should not be more than 6 simultaneously, but better be safe than sorry)
            Ogre::Vector3 edgeCorners[8]; 
            unsigned edgeCornersCount = 0;
            std::pair<unsigned, AxisAlignedBox::CornerEnum> cornerMap[8] = {
                { F|L|B, AxisAlignedBox::FAR_LEFT_BOTTOM }, { F|R|B, AxisAlignedBox::FAR_RIGHT_BOTTOM },
                { F|L|T, AxisAlignedBox::FAR_LEFT_TOP },    { F|R|T, AxisAlignedBox::FAR_RIGHT_TOP },
                { N|L|B, AxisAlignedBox::NEAR_LEFT_BOTTOM },{ N|R|B, AxisAlignedBox::NEAR_RIGHT_BOTTOM },
                { N|L|T, AxisAlignedBox::NEAR_LEFT_TOP },   { N|R|T, AxisAlignedBox::NEAR_RIGHT_TOP }};
            for(auto& c : cornerMap)
                if((lightSidesMask & c.first) != 0 && (lightSidesMask & c.first) != c.first) // if adjacent sides not all lit or all unlit
                    edgeCorners[edgeCornersCount++] = lightCapBounds.getCorner(c.second);
            
            // find max angular size in range [0..pi] by finding min cos of angular size, range [1..-1]
            Real cosAngle = 1.0;
            for(unsigned i0 = 0; i0 + 1 < edgeCornersCount; ++i0)
                for(unsigned i1 = i0 + 1; i1 < edgeCornersCount; ++i1)
                {
                    // 4~6 edge corners, 6~15 angular distance calculations
                    Vector3 a = (edgeCorners[i0] - lightPosition).normalisedCopy();
                    Vector3 b = (edgeCorners[i1] - lightPosition).normalisedCopy();
                    Real cosAB = a.dotProduct(b);
                    if(cosAngle > cosAB)
                        cosAngle  = cosAB;
                }
            
            if(cosAngle < 0.5) // angularSize > 60 degrees
                return false;
        }

        return true;
    }
Пример #5
0
/** Since we are loose, only check the center.
*/
bool OctreeNode::_isIn( AxisAlignedBox &box )
{
	// Always fail if not in the scene graph or box is null
	if (!mIsInSceneGraph || box.isNull()) return false;

	// Always succeed if AABB is infinite
	if (box.isInfinite())
		return true;

    Vector3 center = mWorldAABB.getMaximum().midPoint( mWorldAABB.getMinimum() );

    Vector3 bmin = box.getMinimum();
    Vector3 bmax = box.getMaximum();

    bool centre = ( bmax > center && bmin < center );
	if (!centre)
		return false;

	// Even if covering the centre line, need to make sure this BB is not large
	// enough to require being moved up into parent. When added, bboxes would
	// end up in parent due to cascade but when updating need to deal with
	// bbox growing too large for this child
	Vector3 octreeSize = bmax - bmin;
	Vector3 nodeSize = mWorldAABB.getMaximum() - mWorldAABB.getMinimum();
	return nodeSize < octreeSize;

}
    /** It's assumed the the given box has already been proven to fit into
    * a child.  Since it's a loose octree, only the centers need to be
    * compared to find the appropriate node.
    */
    void Octree::_getChildIndexes( const AxisAlignedBox &box, int *x, int *y, int *z ) const
    {
        Vector3 max = mBox.getMaximum();
        Vector3 min = box.getMinimum();

        Vector3 center = mBox.getMaximum().midPoint( mBox.getMinimum() );

        Vector3 ncenter = box.getMaximum().midPoint( box.getMinimum() );

        if ( ncenter.x > center.x )
            * x = 1;
        else
            *x = 0;

        if ( ncenter.y > center.y )
            * y = 1;
        else
            *y = 0;

        if ( ncenter.z > center.z )
            * z = 1;
        else
            *z = 0;

    }
Пример #7
0
    //-----------------------------------------------------------------------
    bool Math::intersects(const Sphere& sphere, const AxisAlignedBox& box)
    {
        if (box.isNull()) return false;
        if (box.isInfinite()) return true;

        // Use splitting planes
        const Vector3& center = sphere.getCenter();
        Real radius = sphere.getRadius();
        const Vector3& min = box.getMinimum();
        const Vector3& max = box.getMaximum();

        // Arvo's algorithm
        Real s, d = 0;
        for (int i = 0; i < 3; ++i)
        {
            if (center.ptr()[i] < min.ptr()[i])
            {
                s = center.ptr()[i] - min.ptr()[i];
                d += s * s; 
            }
            else if(center.ptr()[i] > max.ptr()[i])
            {
                s = center.ptr()[i] - max.ptr()[i];
                d += s * s; 
            }
        }
        return d <= radius * radius;

    }
Пример #8
0
	ParaEngine::AxisAlignedBox AxisAlignedBox::intersection(const AxisAlignedBox& b2) const
	{
		if (this->isNull() || b2.isNull())
		{
			return AxisAlignedBox();
		}
		else if (this->isInfinite())
		{
			return b2;
		}
		else if (b2.isInfinite())
		{
			return *this;
		}

		Vector3 intMin = mMinimum;
		Vector3 intMax = mMaximum;

		intMin.makeCeil(b2.getMinimum());
		intMax.makeFloor(b2.getMaximum());

		// Check intersection isn't null
		if (intMin.x < intMax.x &&
			intMin.y < intMax.y &&
			intMin.z < intMax.z)
		{
			return AxisAlignedBox(intMin, intMax);
		}

		return AxisAlignedBox();
	}
	/* Find the best (smallest) zone that contains a point
	*/
	PCZone * PCZSceneManager::findZoneForPoint(Vector3 & point)
	{
		PCZone * zone;
		PCZone * bestZone = mDefaultZone;
		Real bestVolume = Ogre::Math::POS_INFINITY;

		ZoneMap::iterator zit = mZones.begin();

		while ( zit != mZones.end() )
		{
			zone = zit->second;
			AxisAlignedBox aabb;
			zone->getAABB(aabb);
			SceneNode * enclosureNode = zone->getEnclosureNode();
			if (enclosureNode != 0)
			{
				// since this is the "local" AABB, add in world translation of the enclosure node
				aabb.setMinimum(aabb.getMinimum() + enclosureNode->_getDerivedPosition());
				aabb.setMaximum(aabb.getMaximum() + enclosureNode->_getDerivedPosition());
			}
			if (aabb.contains(point))
			{
				if (aabb.volume() < bestVolume)
				{
					// this zone is "smaller" than the current best zone, so make it
					// the new best zone
					bestZone = zone;
					bestVolume = aabb.volume();
				}
			}
			// proceed to next zone in the list
			++zit;
		}
		return bestZone;
	}
Пример #10
0
void OctreeSceneManager::resize( const AxisAlignedBox &box )
{
    list< SceneNode * >::type nodes;
    list< SceneNode * >::type ::iterator it;

    _findNodes( mOctree->mBox, nodes, 0, true, mOctree );

    OGRE_DELETE mOctree;

    mOctree = OGRE_NEW Octree( 0 );
    mOctree->mBox = box;

    const Vector3 &min = box.getMinimum();
    const Vector3 &max = box.getMaximum();
    mOctree->mHalfSize = ( max - min ) * 0.5f;

    it = nodes.begin();

    while ( it != nodes.end() )
    {
        OctreeNode * on = static_cast < OctreeNode * > ( *it );
        on -> setOctant( 0 );
        _updateOctreeNode( on );
        ++it;
    }

}
Пример #11
0
    TEST_FIXTURE(ScriptingTestEnvironment, ConvertFiniteAxisAlignedBoxFromJavaScript)
    {
        HandleScope handle_scope;

        Handle<Value> result = pScriptingManager->execute("import_module('Athena.Math'); new Athena.Math.AxisAlignedBox(1, 2, 3, 4, 5, 6);");

        AxisAlignedBox aab = fromJSAxisAlignedBox(result);

        CHECK(aab.isFinite());
        CHECK_CLOSE(1.0f, aab.getMinimum().x, 1e-6f);
        CHECK_CLOSE(2.0f, aab.getMinimum().y, 1e-6f);
        CHECK_CLOSE(3.0f, aab.getMinimum().z, 1e-6f);
        CHECK_CLOSE(4.0f, aab.getMaximum().x, 1e-6f);
        CHECK_CLOSE(5.0f, aab.getMaximum().y, 1e-6f);
        CHECK_CLOSE(6.0f, aab.getMaximum().z, 1e-6f);
    }
Пример #12
0
    void Actor::setHighlighted(bool highlight)
    {
        if (highlight != mHighlighted)
        {
            //getControlledObject()->setHighlighted(highlight);
            mHighlighted = highlight;
        }

        if (mHighlighted && mDescription == NULL)
        {
			if (mSceneNode != NULL)
			{
				mDescription = new MovableText(mName + "_desc", mName);
				mDescription->showOnTop(true);
				mDescription->setAlignment(MovableText::ALIGN_CENTER);
				if (mActorControlledObject && mActorControlledObject->isMeshObject())
				{
					MeshObject* mo = static_cast<MeshObject*>(mActorControlledObject);
					AxisAlignedBox aabb = mo->getDefaultSize();
					mDescription->setPositionOffset(Vector3(0, aabb.getMaximum().y * 1.1, 0));
				}

				mSceneNode->attachObject(mDescription);
			}
        }
        else if (mDescription)
        {
            mDescription->setVisible(highlight);
        }
    }
Пример #13
0
/** Checks how the box intersects with the sphere.
*/
Intersection intersect( const Sphere &one, const AxisAlignedBox &two )
{
    OctreeSceneManager::intersect_call++;
    // Null box?
    if (two.isNull()) return OUTSIDE;
    if (two.isInfinite()) return INTERSECT;

    float sradius = one.getRadius();

    sradius *= sradius;

    Vector3 scenter = one.getCenter();

    const Vector3& twoMin = two.getMinimum();
    const Vector3& twoMax = two.getMaximum();

    float s, d = 0;

    Vector3 mndistance = ( twoMin - scenter );
    Vector3 mxdistance = ( twoMax - scenter );

    if ( mndistance.squaredLength() < sradius &&
            mxdistance.squaredLength() < sradius )
    {
        return INSIDE;
    }

    //find the square of the distance
    //from the sphere to the box
    for ( int i = 0 ; i < 3 ; i++ )
    {
        if ( scenter[ i ] < twoMin[ i ] )
        {
            s = scenter[ i ] - twoMin[ i ];
            d += s * s;
        }

        else if ( scenter[ i ] > twoMax[ i ] )
        {
            s = scenter[ i ] - twoMax[ i ];
            d += s * s;
        }

    }

    bool partial = ( d <= sradius );

    if ( !partial )
    {
        return OUTSIDE;
    }

    else
    {
        return INTERSECT;
    }


}
Пример #14
0
	String StringConv::axisAlignedBoxToString(const AxisAlignedBox& _val, size_t _precision)
	{
		String r;
		r += toString(_val.getMinimum(), _precision);
		r += " ";
		r += toString(_val.getMaximum(), _precision);
		return r;
	}
Пример #15
0
    // ------------------------------------------------------------------------
    void ShadowCaster::extrudeBounds(AxisAlignedBox& box, const Vector4& light, Real extrudeDist) const
    {
        Vector3 extrusionDir;

        if (light.w == 0)
        {
            // Parallel projection guarantees min/max relationship remains the same
            extrusionDir.x = -light.x;
            extrusionDir.y = -light.y;
            extrusionDir.z = -light.z;
            extrusionDir.normalise();
            extrusionDir *= extrudeDist;
            box.setExtents(box.getMinimum() + extrusionDir, 
                box.getMaximum() + extrusionDir);
        }
        else
        {
            Vector3 vmin, vmax;
            Vector3 corner, tmp;

#define __EXTRUDE_POINT()                               \
            {                                           \
                extrusionDir.x = corner.x - light.x;    \
                extrusionDir.y = corner.y - light.y;    \
                extrusionDir.z = corner.z - light.z;    \
                extrusionDir.normalise();               \
                extrusionDir *= extrudeDist;            \
                tmp = corner + extrusionDir;            \
            }
            corner = box.getMinimum(); __EXTRUDE_POINT(); vmin = vmax = tmp;
            corner.x = box.getMaximum().x; __EXTRUDE_POINT(); vmin.makeFloor(tmp); vmax.makeCeil(tmp);
            corner.y = box.getMaximum().y; __EXTRUDE_POINT(); vmin.makeFloor(tmp); vmax.makeCeil(tmp);
            corner.x = box.getMinimum().x; __EXTRUDE_POINT(); vmin.makeFloor(tmp); vmax.makeCeil(tmp);
            corner.z = box.getMaximum().z; __EXTRUDE_POINT(); vmin.makeFloor(tmp); vmax.makeCeil(tmp);
            corner.x = box.getMaximum().x; __EXTRUDE_POINT(); vmin.makeFloor(tmp); vmax.makeCeil(tmp);
            corner.y = box.getMinimum().y; __EXTRUDE_POINT(); vmin.makeFloor(tmp); vmax.makeCeil(tmp);
            corner.x = box.getMinimum().x; __EXTRUDE_POINT(); vmin.makeFloor(tmp); vmax.makeCeil(tmp);
#undef __EXTRUDE_POINT


            box.setExtents(vmin, vmax);

        }

    }
Пример #16
0
  void TerrainInfo::setExtents(const AxisAlignedBox& extents)
  {
    if (mWidth == 0)
      OGRE_EXCEPT(Exception::ERR_INVALID_STATE, "You must set a heightmap first.", "TerrainInfo::setExtents");

    mOffset = extents.getMinimum();
    mScale = extents.getMaximum() - extents.getMinimum();
    mScale.x /= mWidth;
    mScale.z /= mHeight;
  }
Пример #17
0
	void DebugDisplay::drawCube( AxisAlignedBox bbox )
	{
		oht_assert_threadmodel(ThrMdl_Main);

		ManualObject * pManObj = _pSceneManager->createManualObject();

		rollbackTransforms(bbox);

		pManObj->begin(getCurrentMaterial(), RenderOperation::OT_LINE_LIST);

		const Vector3
			m0 = bbox.getMinimum(),
			mN = bbox.getMaximum();

		pManObj->position(m0.x, m0.y, m0.z);
		pManObj->position(mN.x, m0.y, m0.z);

		pManObj->position(m0.x, m0.y, m0.z);
		pManObj->position(m0.x, mN.y, m0.z);

		pManObj->position(m0.x, m0.y, m0.z);
		pManObj->position(m0.x, m0.y, mN.z);

		pManObj->position(mN.x, mN.y, m0.z);
		pManObj->position(mN.x, m0.y, m0.z);

		pManObj->position(mN.x, mN.y, m0.z);
		pManObj->position(m0.x, mN.y, m0.z);

		pManObj->position(mN.x, mN.y, m0.z);
		pManObj->position(mN.x, mN.y, mN.z);

		pManObj->position(m0.x, mN.y, mN.z);
		pManObj->position(m0.x, mN.y, m0.z);

		pManObj->position(m0.x, mN.y, mN.z);
		pManObj->position(m0.x, m0.y, mN.z);

		pManObj->position(m0.x, mN.y, mN.z);
		pManObj->position(mN.x, mN.y, mN.z);

		pManObj->position(mN.x, m0.y, mN.z);
		pManObj->position(m0.x, m0.y, mN.z);

		pManObj->position(mN.x, m0.y, mN.z);
		pManObj->position(mN.x, m0.y, m0.z);

		pManObj->position(mN.x, m0.y, mN.z);
		pManObj->position(mN.x, mN.y, mN.z);

		pManObj->end();

		_pScNode->attachObject(pManObj);
	}
Пример #18
0
  std::pair<bool, Vector3> TerrainInfo::rayIntersects(const Ray& ray) const
  {
    AxisAlignedBox box = getExtents();
    Vector3 point = ray.getOrigin();
    Vector3 dir = ray.getDirection();

    // first, does the ray start from inside the terrain extents?
    if (!box.contains(point))
    {
      // not inside the box, so let's see if we are actually
      // colliding with it
      pair<bool, Real> res = ray.intersects(box);
      if (!res.first)
        return make_pair(false, Vector3::ZERO);
      // update point to the collision position
      point = ray.getPoint(res.second);
    }

    // now move along the ray until we intersect or leave the bounding box
    while (true)
    {
      // have we arived at or under the terrain height?
      // note that this approach means that ray queries from below won't work
      // correctly, but then again, that shouldn't be a usual case...
      float height = getHeightAt(point.x, point.z);
      if (point.y <= height)
      {
        point.y = height;
        return make_pair(true, point);
      }

      // move further...
      point += dir;

      // check if we are still inside the boundaries
      if (point.x < box.getMinimum().x || point.z < box.getMinimum().z
        || point.x > box.getMaximum().x || point.z > box.getMaximum().z)
        return make_pair(false, Vector3::ZERO);

    }
  }
Пример #19
0
    /** Returns true is the box will fit in a child.
    */
    bool PagingLandScapeOctree::_isNotCrossingAxes(const AxisAlignedBox &box) const
    { 
        const Vector3 &boxMin = box.getMinimum();
        const Vector3 &boxMax = box.getMaximum();

        const Vector3 octCullCenter = mCullBox.getMinimum() + mCullHalfSize;   

        return !((boxMin.x <= octCullCenter.x && octCullCenter.x <= boxMax.x) ||
                 (boxMin.y <= octCullCenter.y && octCullCenter.y <= boxMax.y) ||
                 (boxMin.z <= octCullCenter.z && octCullCenter.z <= boxMax.z));

    }
Пример #20
0
    //---------------------------------------------------------------------
    Real Math::boundingRadiusFromAABB(const AxisAlignedBox& aabb)
    {
        Vector3 max = aabb.getMaximum();
        Vector3 min = aabb.getMinimum();

        Vector3 magnitude = max;
        magnitude.makeCeil(-max);
        magnitude.makeCeil(min);
        magnitude.makeCeil(-min);

        return magnitude.length();
    }
Пример #21
0
	Real MathUtil::distance(const AxisAlignedBox& b1, const AxisAlignedBox& b2)
	{
		if (b1.intersects(b2))
		{
			return 0.0f;
		}
		else
		{
			Vector3 dv;

			const Vector3& min1 = b1.getMinimum();
			const Vector3& min2 = b2.getMinimum();
			const Vector3& max1 = b1.getMaximum();
			const Vector3& max2 = b2.getMaximum();

			dv.x = min1.x > max2.x ? min1.x - max2.x : min2.x > max1.x ? min2.x - max1.x : 0.0f;
			dv.y = min1.y > max2.y ? min1.y - max2.y : min2.y > max1.y ? min2.y - max1.y : 0.0f;
			dv.z = min1.z > max2.z ? min1.z - max2.z : min2.z > max1.z ? min2.z - max1.z : 0.0f;

			return dv.length();
		}
	}
	// -------------------------------------------------------------------------
	CollisionsWorld::CollisionsWorld(SceneManager *scn, const AxisAlignedBox &bounds, bool init, bool set32bitsAxisSweep, unsigned int maxHandles):
mScnMgr(scn),
mBounds(bounds),
mShowDebugShapes(false),
mShowDebugContactPoints(false),
mDebugContactPoints(0),
mDebugDrawer(0)
{
	mDispatcher = new btCollisionDispatcher(&mDefaultCollisionConfiguration);

	if (set32bitsAxisSweep)
	{
		mBroadphase = new bt32BitAxisSweep3(
			OgreBtConverter::to(bounds.getMinimum()), 
			OgreBtConverter::to(bounds.getMaximum()), maxHandles);
	}
	else
	{
        if(maxHandles > USHRT_MAX)
        {
            Ogre::String logNote("Exceeded the maximum number of handles for btAxisSweep3. Max = USHRT_MAX. Resetting maxHandles to USHRT_MAX in OgreBulletCollisions::CollisionsWorld::CollisionsWorld().");
            Ogre::LogManager::getSingleton().logMessage(logNote);
            maxHandles = USHRT_MAX;
        }

		mBroadphase = new btAxisSweep3(
			OgreBtConverter::to(bounds.getMinimum()), 
			OgreBtConverter::to(bounds.getMaximum()), static_cast<unsigned short>(maxHandles));
	}

	// if not called by a inherited class
	if (init)
	{
		mWorld = new btCollisionWorld(mDispatcher, mBroadphase, &mDefaultCollisionConfiguration);

		btCollisionDispatcher * dispatcher = static_cast<btCollisionDispatcher *>(mWorld->getDispatcher());
		btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher);
	}
}
Пример #23
0
/** Checks how the second box intersects with the first.
*/
Intersection intersect( const AxisAlignedBox &one, const AxisAlignedBox &two )
{
    OctreeSceneManager::intersect_call++;
    // Null box?
    if (one.isNull() || two.isNull()) return OUTSIDE;
    if (one.isInfinite()) return INSIDE;
    if (two.isInfinite()) return INTERSECT;


    const Vector3& insideMin = two.getMinimum();
    const Vector3& insideMax = two.getMaximum();

    const Vector3& outsideMin = one.getMinimum();
    const Vector3& outsideMax = one.getMaximum();

    if (    insideMax.x < outsideMin.x ||
            insideMax.y < outsideMin.y ||
            insideMax.z < outsideMin.z ||
            insideMin.x > outsideMax.x ||
            insideMin.y > outsideMax.y ||
            insideMin.z > outsideMax.z )
    {
        return OUTSIDE;
    }

    bool full = ( insideMin.x > outsideMin.x &&
                  insideMin.y > outsideMin.y &&
                  insideMin.z > outsideMin.z &&
                  insideMax.x < outsideMax.x &&
                  insideMax.y < outsideMax.y &&
                  insideMax.z < outsideMax.z );

    if ( full )
        return INSIDE;
    else
        return INTERSECT;

}
Пример #24
0
    void PhysicsManager::addLevelGeometry( Ogre::Entity* levelEntity, const std::vector<OgreNewt::CollisionPtr> &collisions)
    {
        RlAssert1(levelEntity);
        RlAssert1(levelEntity->getParentSceneNode());

        SceneNode* node = levelEntity->getParentSceneNode();
        //Level entity has to be attached to a scene node.
        

        // try one compound collision for the entity if there are several collisions
        OgreNewt::CollisionPtr collision;
        switch( collisions.size() )
        {
            case 0:
                break;
            case 1:
                collision = collisions[0];
                break;
            default:
                collision = OgreNewt::CollisionPtr(new OgreNewt::CollisionPrimitives::CompoundCollision(mWorld, collisions, 0));
                break;
        }

        if( collision )
        {
            OgreNewt::Body* body = new OgreNewt::Body(mWorld, collision );


            body->attachNode(node);
            body->setPositionOrientation(node->_getDerivedPosition(),
                node->_getDerivedOrientation());
            body->setMaterialGroupID(getMaterialID("level"));

            mLevelBodiesQuadTree.add(body);
            //mLevelBodies.push_back(body);
        }

        // adjust worldAABB
        Vector3 minV(mWorldAABB.getMinimum());
        Vector3 maxV(mWorldAABB.getMaximum());

        AxisAlignedBox entityAABB = levelEntity->getWorldBoundingBox(true);
        minV.makeFloor(entityAABB.getMinimum());
        maxV.makeCeil(entityAABB.getMaximum());
        mWorldAABB.setMinimum(minV - Vector3(50, 50, 50));
        mWorldAABB.setMaximum(maxV + Vector3(50, 50, 50));

        mWorld->setWorldSize(mWorldAABB);
    }
Пример #25
0
DiMeshPtr ModelConverter::WriteMesh( const Ogre::Mesh* pMesh )
{
	DiMeshPtr model = Demi::DiAssetManager::GetInstancePtr(
		)->CreateOrReplaceAsset<DiMesh>(pMesh->getName().c_str());

	// write AABB
	AxisAlignedBox aabb = pMesh->getBounds();
	DiAABB maabb;
	maabb.SetExtents(aabb.getMinimum().x,aabb.getMinimum().y,aabb.getMinimum().z,
		aabb.getMaximum().x,aabb.getMaximum().y,aabb.getMaximum().z);
	model->SetBounds(maabb);

	// write sub meshes
	for (int i = 0; i < pMesh->getNumSubMeshes(); ++i)
	{
		DiSubMesh* sub = model->CreateSubMesh();

		LogManager::getSingleton().logMessage("Writing submesh...");
		WriteSubMesh(sub, pMesh->getSubMesh(i));
		LogManager::getSingleton().logMessage("Submesh exported.");
	}

	return model;
}
Пример #26
0
	/* get the aabb of the zone - default implementation
	   uses the enclosure node, but there are other perhaps
	   better ways
	*/
	void PCZone::getAABB(AxisAlignedBox & aabb)
	{
		// if there is no node, just return a null box
		if (mEnclosureNode == 0)
		{
			aabb.setNull();
		}
		else
		{
			aabb = mEnclosureNode->_getWorldAABB();
			// since this is the "local" AABB, subtract out any translations
			aabb.setMinimum(aabb.getMinimum() - mEnclosureNode->_getDerivedPosition());
			aabb.setMaximum(aabb.getMaximum() - mEnclosureNode->_getDerivedPosition());
		}
		return;
	}
Пример #27
0
void SplineRoad::AddMesh(MeshPtr mesh, String sMesh, const AxisAlignedBox& aabox,
	Entity** pEnt, SceneNode** pNode, String sEnd)
{
	mesh->_setBounds(aabox);
	mesh->_setBoundingSphereRadius((aabox.getMaximum()-aabox.getMinimum()).length()/2.0);  
	mesh->load();
	unsigned short src, dest;
	if (!mesh->suggestTangentVectorBuildParams(VES_TANGENT, src, dest))
		mesh->buildTangentVectors(VES_TANGENT, src, dest);

	*pEnt = mSceneMgr->createEntity("rd.ent"+sEnd, sMesh);
	*pNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("rd.node"+sEnd);
	(*pNode)->attachObject(*pEnt);
	(*pEnt)->setVisible(false);  (*pEnt)->setCastShadows(false);
	(*pEnt)->setVisibilityFlags(RV_Road);
}
Пример #28
0
	//-----------------------------------------------------------------------
	void ConvexBody::clip(const AxisAlignedBox& aab)
	{
		// only process finite boxes
		if (!aab.isFinite())
			return;
		// ordering of the AAB points:
		//		1-----2
		//	   /|    /|
		//	  / |   / |
		//   5-----4  |
		//   |  0--|--3
		//   | /   | /
		//   |/    |/
		//   6-----7

		const Vector3& min = aab.getMinimum();
		const Vector3& max = aab.getMaximum();

		// clip object for each plane of the AAB
		Plane p;


		// front
		p.redefine(Vector3::UNIT_Z, max);
		clip(p);

		// back
		p.redefine(Vector3::NEGATIVE_UNIT_Z, min);
		clip(p);
		
		// left
		p.redefine(Vector3::NEGATIVE_UNIT_X, min);
		clip(p);
		
		// right
		p.redefine(Vector3::UNIT_X, max);
		clip(p);
		
		// bottom
		p.redefine(Vector3::NEGATIVE_UNIT_Y, min);
		clip(p);
		
		// top
		p.redefine(Vector3::UNIT_Y, max);
		clip(p);

	}
//------------------------------------------------------------------------------
void SegmentedDynamicLightManager::calculateLightBounds(const Light* i_Light, LightData& o_LightData)
{ 
	Real lightRange = i_Light->getAttenuationRange();
	const Vector3& lightPosition = i_Light->getDerivedPosition(true);

	AxisAlignedBox boundBox(lightPosition - lightRange, lightPosition + lightRange);

	if (i_Light->getType() == Light::LT_SPOTLIGHT)
	{
		static const Radian c_RadianPI(Math::PI);
		static const Radian c_RadianZero(0);

		Radian halfOuterAngle = i_Light->getSpotlightOuterAngle() * 0.5;
		Real boxOffset = Math::Sin(halfOuterAngle) * lightRange;
		const Vector3& lightDirection = i_Light->getDerivedDirection();

		Radian dirUpAngle(fabs(Math::ASin(lightDirection.y).valueRadians()));
		Radian dirUpMaxAngle = std::max<Radian>(dirUpAngle - halfOuterAngle,c_RadianZero);
		Radian dirUpMinAngle = std::min<Radian>(dirUpAngle + halfOuterAngle, c_RadianPI);
		Real dirDistanceMax = Math::Cos(dirUpMaxAngle) * lightRange;
		Real dirDistanceMin = Math::Cos(dirUpMinAngle) * lightRange;
			
		Vector3 flatDirection(lightDirection.x, 0, lightDirection.z);
		Real flatDirLen = flatDirection.length();
		if (flatDirLen != 0) flatDirection /= flatDirLen; 
		else flatDirection = Vector3(1,0,0);

		Vector3 flatDirectionPerp(flatDirection.z, 0, -flatDirection.x);
		flatDirectionPerp *= boxOffset;

		Vector3 flatPositionMax = lightPosition + dirDistanceMax * flatDirection;
		Vector3 flatPositionMin = lightPosition + dirDistanceMin * flatDirection;

		AxisAlignedBox spotBox;
		spotBox.merge(flatPositionMax + flatDirectionPerp);
		spotBox.merge(flatPositionMax - flatDirectionPerp);
		spotBox.merge(flatPositionMin + flatDirectionPerp);
		spotBox.merge(flatPositionMin - flatDirectionPerp);
		spotBox.merge(lightPosition);
			
		boundBox.getMaximum().makeFloor(spotBox.getMaximum());
		boundBox.getMinimum().makeCeil(spotBox.getMinimum());
	}

	o_LightData.setBounds(boundBox);
}
Пример #30
0
void OctreeSceneManager::init( AxisAlignedBox &box, int depth )
{
    delete mSceneRoot; //get rid of old root.

    // -- Changes by Steve
    // Don't do it this way, it will add it to the mSceneNodes which we don't want
    //mSceneRoot = createSceneNode( "SceneRoot" );
    mSceneRoot = new OctreeNode( this, "SceneRoot" );
	mSceneRoot->_notifyRootNode();
    // -- End changes by Steve

    if ( mOctree != 0 )
        delete mOctree;

    mOctree = new Octree( 0 );

    mMaxDepth = depth;
    mBox = box;

    mOctree -> mBox = box;

    Vector3 min = box.getMinimum();

    Vector3 max = box.getMaximum();

    mOctree -> mHalfSize = ( max - min ) / 2;


    mShowBoxes = false;

    mNumObjects = 0;

    Vector3 v( 1.5, 1.5, 1.5 );

    mScaleFactor.setScale( v );



    // setDisplaySceneNodes( true );
    // setShowBoxes( true );

    //
    //mSceneRoot isn't put into the octree since it has no volume.

}