コード例 #1
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();
		}
	}
コード例 #2
0
	void COctreeTriangleSelector::getTrianglesFromOctree(
		SOctreeNode* node, SINT32& trianglesWritten,
		SINT32 maximumSize, const AxisAlignedBox& box,
		const Matrix4* mat, triangle3df* triangles) const
	{
		if (!box.intersects(node->Box))    //if (!box.intersectsWithBox(node->Box))
			return;

		const UINT32 cnt = node->Triangles.size();

		for (UINT32 i = 0; i<cnt; ++i)
		{
			const triangle3df& srcTri = node->Triangles[i];
			// This isn't an accurate test, but it's fast, and the 
			// API contract doesn't guarantee complete accuracy.
			if (srcTri.isTotalOutsideBox(box))
				continue;

			triangle3df& dstTri = triangles[trianglesWritten];
			//mat->transformVect(dstTri.pointA, srcTri.pointA
			//mat->transformVect(dstTri.pointB, srcTri.pointB);
			//mat->transformVect(dstTri.pointC, srcTri.pointC);
			dstTri.pointA = mat->transformAffine(srcTri.pointA);
			dstTri.pointB = mat->transformAffine(srcTri.pointB);
			dstTri.pointC = mat->transformAffine(srcTri.pointC);
			++trianglesWritten;

			// Halt when the out array is full.
			if (trianglesWritten == maximumSize)
				return;
		}

		for (UINT32 i = 0; i<8; ++i)
			if (node->Child[i])
				getTrianglesFromOctree(node->Child[i], trianglesWritten,
				maximumSize, box, mat, triangles);
	}
コード例 #3
0
ファイル: OgreLight.cpp プロジェクト: bsmr-c-cpp/ogre
    //-----------------------------------------------------------------------
    bool Light::isInLightRange(const Ogre::AxisAlignedBox& container) const
    {
        bool isIntersect = true;
        //Check the 2 simple / obvious situations. Light is directional or light source is inside the container
        if ((mLightType != LT_DIRECTIONAL) && (container.intersects(mDerivedPosition) == false))
        {
            //Check that the container is within the sphere of the light
            isIntersect = Math::intersects(Sphere(mDerivedPosition, mRange),container);
            //If this is a spotlight, do a more specific check
            if ((isIntersect) && (mLightType == LT_SPOTLIGHT) && (mSpotOuter.valueRadians() <= Math::PI))
            {
                //Create a rough bounding box around the light and check if
                Quaternion localToWorld = Vector3::NEGATIVE_UNIT_Z.getRotationTo(mDerivedDirection);

                Real boxOffset = Math::Sin(mSpotOuter * 0.5) * mRange;
                AxisAlignedBox lightBoxBound;
                lightBoxBound.merge(Vector3::ZERO);
                lightBoxBound.merge(localToWorld * Vector3(boxOffset, boxOffset, -mRange));
                lightBoxBound.merge(localToWorld * Vector3(-boxOffset, boxOffset, -mRange));
                lightBoxBound.merge(localToWorld * Vector3(-boxOffset, -boxOffset, -mRange));
                lightBoxBound.merge(localToWorld * Vector3(boxOffset, -boxOffset, -mRange));
                lightBoxBound.setMaximum(lightBoxBound.getMaximum() + mDerivedPosition);
                lightBoxBound.setMinimum(lightBoxBound.getMinimum() + mDerivedPosition);
                isIntersect = lightBoxBound.intersects(container);
                
                //If the bounding box check succeeded do one more test
                if (isIntersect)
                {
                    //Check intersection again with the bounding sphere of the container
                    //Helpful for when the light is at an angle near one of the vertexes of the bounding box
                    isIntersect = isInLightRange(Sphere(container.getCenter(), 
                        container.getHalfSize().length()));
                }
            }
        }
        return isIntersect;
    }
コード例 #4
0
	//-----------------------------------------------------------------------
	void BoxCollider::_affect(ParticleTechnique* particleTechnique, Particle* particle, Real timeElapsed)
	{
		mPredictedPosition = particle->position + mVelocityScale * particle->direction;
		bool collision = false;

		/** Collision detection is a two-step. First, we determine whether the particle is now colliding.
			If it is, the particle is re-positioned. However, a timeElapsed value is used, which is not the same
			as the one that was used at the moment before the particle was colliding. Therefore, we rather 
			want to predict particle collision in front. This probably isn't the fastest solution.
			The same approach was used for the other colliders.
		*/
		switch(mIntersectionType)
		{
			case BaseCollider::IT_POINT:
			{
				// Validate for a point-box intersection
				if (mInnerCollision != mBox.intersects(particle->position))
				{
					// Collision detected (re-position the particle)
					particle->position -= mVelocityScale * particle->direction;
					collision = true;
				}
				else if (mInnerCollision != mBox.intersects(mPredictedPosition))
				{
					// Collision detected
					collision = true;
				}
			}
			break;

			case BaseCollider::IT_BOX:
			{
				// Validate for a box-box intersection
				if (particle->particleType != Particle::PT_VISUAL)
					break;

				VisualParticle* visualParticle = static_cast<VisualParticle*>(particle);
				AxisAlignedBox box;
				populateAlignedBox(box,
					visualParticle->position, 
					visualParticle->width, 
					visualParticle->height,
					visualParticle->depth);

				if (mInnerCollision != box.intersects(mBox))
				{
					// Collision detected (re-position the particle)
					particle->position -= mVelocityScale * particle->direction;
					collision = true;
				}
				else
				{
					AxisAlignedBox box;
					populateAlignedBox(box,
						mPredictedPosition, 
						visualParticle->width, 
						visualParticle->height,
						visualParticle->depth);
					if (mInnerCollision != box.intersects(mBox))
					{
						// Collision detected
						collision = true;
					}
				}
			}
			break;
		}

		if (collision)
		{
			calculateDirectionAfterCollision(particle);
			calculateRotationSpeedAfterCollision(particle);
			particle->addEventFlags(Particle::PEF_COLLIDED);
		}
	}
コード例 #5
0
	// --- find nodes which intersect various types of BV's ---
	void DefaultZone::_findNodes( const AxisAlignedBox &t, 
								  PCZSceneNodeList &list, 
								  PortalList &visitedPortals,
								  bool includeVisitors,
								  bool recurseThruPortals,
								  PCZSceneNode *exclude )
	{
		// if this zone has an enclosure, check against the enclosure AABB first
		if (mEnclosureNode)
		{
			if (!mEnclosureNode->_getWorldAABB().intersects(t))
			{
				// AABB of zone does not intersect t, just return.
				return;
			}
		}

		// check nodes at home in this zone
	    PCZSceneNodeList::iterator it = mHomeNodeList.begin();
	    while ( it != mHomeNodeList.end() )
	    {
			PCZSceneNode * pczsn = *it;
			if ( pczsn != exclude )
			{
				// make sure node is not already in the list (might have been added in another
				// zone it was visiting)
				PCZSceneNodeList::iterator it2 = list.find(pczsn);
				if (it2 == list.end())
				{
					bool nsect = t.intersects( pczsn -> _getWorldAABB() );
					if ( nsect )
					{
						list.insert( pczsn );
					}
				}
			}
		    ++it;
	    }

		if (includeVisitors)
		{
			// check visitor nodes
			PCZSceneNodeList::iterator iter = mVisitorNodeList.begin();
			while ( iter != mVisitorNodeList.end() )
			{
				PCZSceneNode * pczsn = *iter;
				if ( pczsn != exclude )
				{
					// make sure node is not already in the list (might have been added in another
					// zone it was visiting)
					PCZSceneNodeList::iterator it2 = list.find(pczsn);
					if (it2 == list.end())
					{
						bool nsect = t.intersects( pczsn -> _getWorldAABB() );
						if ( nsect )
						{
							list.insert( pczsn );
						}
					}
				}
				++iter;
			}
		}

        // if asked to, recurse through portals
        if (recurseThruPortals)
        {
            PortalList::iterator pit = mPortals.begin();
            while ( pit != mPortals.end() )
            {
                Portal * portal = *pit;
			    // check portal versus bounding box
				if (portal->intersects(t))
			    {
                    // make sure portal hasn't already been recursed through
                    PortalList::iterator pit2 = std::find(visitedPortals.begin(), visitedPortals.end(), portal);
                    if (pit2 == visitedPortals.end())
                    {
                        // save portal to the visitedPortals list
                        visitedPortals.push_front(portal);
				        // recurse into the connected zone 
				        portal->getTargetZone()->_findNodes(t, 
														    list, 
                                                            visitedPortals,
														    includeVisitors, 
														    recurseThruPortals, 
														    exclude);
                    }
			    }
			    pit++;
		    }
        }
    }