Projekt_Grafika/dependencies/physx-4.1/source/physxextensions/src/ExtSceneQueryExt.cpp

189 lines
7.0 KiB
C++

//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved.
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
#include "extensions/PxSceneQueryExt.h"
using namespace physx;
bool PxSceneQueryExt::raycastAny( const PxScene& scene,
const PxVec3& origin, const PxVec3& unitDir, const PxReal distance,
PxSceneQueryHit& hit, const PxSceneQueryFilterData& filterData,
PxSceneQueryFilterCallback* filterCall, const PxSceneQueryCache* cache)
{
PxSceneQueryFilterData fdAny = filterData;
fdAny.flags |= PxQueryFlag::eANY_HIT;
PxRaycastBuffer buf;
scene.raycast(origin, unitDir, distance, buf, PxHitFlags(), fdAny, filterCall, cache);
hit = buf.block;
return buf.hasBlock;
}
bool PxSceneQueryExt::raycastSingle(const PxScene& scene,
const PxVec3& origin, const PxVec3& unitDir, const PxReal distance,
PxSceneQueryFlags outputFlags, PxRaycastHit& hit,
const PxSceneQueryFilterData& filterData,
PxSceneQueryFilterCallback* filterCall, const PxSceneQueryCache* cache)
{
PxRaycastBuffer buf;
PxQueryFilterData fd1 = filterData;
scene.raycast(origin, unitDir, distance, buf, outputFlags, fd1, filterCall, cache);
hit = buf.block;
return buf.hasBlock;
}
PxI32 PxSceneQueryExt::raycastMultiple( const PxScene& scene,
const PxVec3& origin, const PxVec3& unitDir, const PxReal distance,
PxSceneQueryFlags outputFlags,
PxRaycastHit* hitBuffer, PxU32 hitBufferSize, bool& blockingHit,
const PxSceneQueryFilterData& filterData,
PxSceneQueryFilterCallback* filterCall, const PxSceneQueryCache* cache)
{
PxRaycastBuffer buf(hitBuffer, hitBufferSize);
PxQueryFilterData fd1 = filterData;
scene.raycast(origin, unitDir, distance, buf, outputFlags, fd1, filterCall, cache);
blockingHit = buf.hasBlock;
if(blockingHit)
{
if(buf.nbTouches < hitBufferSize)
{
hitBuffer[buf.nbTouches] = buf.block;
return PxI32(buf.nbTouches+1);
}
else // overflow, drop the last touch
{
hitBuffer[hitBufferSize-1] = buf.block;
return -1;
}
} else
// no block
return PxI32(buf.nbTouches);
}
bool PxSceneQueryExt::sweepAny( const PxScene& scene,
const PxGeometry& geometry, const PxTransform& pose, const PxVec3& unitDir, const PxReal distance,
PxSceneQueryFlags queryFlags,
PxSceneQueryHit& hit,
const PxSceneQueryFilterData& filterData,
PxSceneQueryFilterCallback* filterCall,
const PxSceneQueryCache* cache,
PxReal inflation)
{
PxSceneQueryFilterData fdAny = filterData;
fdAny.flags |= PxQueryFlag::eANY_HIT;
PxSweepBuffer buf;
scene.sweep(geometry, pose, unitDir, distance, buf, queryFlags, fdAny, filterCall, cache, inflation);
hit = buf.block;
return buf.hasBlock;
}
bool PxSceneQueryExt::sweepSingle( const PxScene& scene,
const PxGeometry& geometry, const PxTransform& pose, const PxVec3& unitDir, const PxReal distance,
PxSceneQueryFlags outputFlags,
PxSweepHit& hit,
const PxSceneQueryFilterData& filterData,
PxSceneQueryFilterCallback* filterCall,
const PxSceneQueryCache* cache,
PxReal inflation)
{
PxSweepBuffer buf;
PxQueryFilterData fd1 = filterData;
scene.sweep(geometry, pose, unitDir, distance, buf, outputFlags, fd1, filterCall, cache, inflation);
hit = buf.block;
return buf.hasBlock;
}
PxI32 PxSceneQueryExt::sweepMultiple( const PxScene& scene,
const PxGeometry& geometry, const PxTransform& pose, const PxVec3& unitDir, const PxReal distance,
PxSceneQueryFlags outputFlags, PxSweepHit* hitBuffer, PxU32 hitBufferSize, bool& blockingHit,
const PxSceneQueryFilterData& filterData,
PxSceneQueryFilterCallback* filterCall, const PxSceneQueryCache* cache,
PxReal inflation)
{
PxQueryFilterData fd1 = filterData;
PxSweepBuffer buf(hitBuffer, hitBufferSize);
scene.sweep(geometry, pose, unitDir, distance, buf, outputFlags, fd1, filterCall, cache, inflation);
blockingHit = buf.hasBlock;
if(blockingHit)
{
if(buf.nbTouches < hitBufferSize)
{
hitBuffer[buf.nbTouches] = buf.block;
return PxI32(buf.nbTouches+1);
}
else // overflow, drop the last touch
{
hitBuffer[hitBufferSize-1] = buf.block;
return -1;
}
} else
// no block
return PxI32(buf.nbTouches);
}
PxI32 PxSceneQueryExt::overlapMultiple( const PxScene& scene,
const PxGeometry& geometry, const PxTransform& pose,
PxOverlapHit* hitBuffer, PxU32 hitBufferSize,
const PxSceneQueryFilterData& filterData,
PxSceneQueryFilterCallback* filterCall)
{
PxQueryFilterData fd1 = filterData;
fd1.flags |= PxQueryFlag::eNO_BLOCK;
PxOverlapBuffer buf(hitBuffer, hitBufferSize);
scene.overlap(geometry, pose, buf, fd1, filterCall);
if(buf.hasBlock)
{
if(buf.nbTouches < hitBufferSize)
{
hitBuffer[buf.nbTouches] = buf.block;
return PxI32(buf.nbTouches+1);
}
else // overflow, drop the last touch
{
hitBuffer[hitBufferSize-1] = buf.block;
return -1;
}
} else
// no block
return PxI32(buf.nbTouches);
}
bool PxSceneQueryExt::overlapAny( const PxScene& scene,
const PxGeometry& geometry, const PxTransform& pose,
PxOverlapHit& hit,
const PxSceneQueryFilterData& filterData,
PxSceneQueryFilterCallback* filterCall)
{
PxSceneQueryFilterData fdAny = filterData;
fdAny.flags |= (PxQueryFlag::eANY_HIT | PxQueryFlag::eNO_BLOCK);
PxOverlapBuffer buf;
scene.overlap(geometry, pose, buf, fdAny, filterCall);
hit = buf.block;
return buf.hasBlock;
}