virtual void setFrame(PxU32 frameNo) { if ( mReadAccess && (frameNo+1) < mFrameCount && (frameNo+1) != mCurrentFrame ) { mPrimitiveBatch.resize(0); FrameHeader &h = mFrameHeaders[frameNo]; mCurrentFrame = frameNo+1; reset(); mPrimitiveCount = h.mItemCount; mPrimitives = (const DebugPrimitive **)PX_ALLOC( sizeof(DebugPrimitive *)*mPrimitiveCount, PX_DEBUG_EXP("DebugPrimitive")); mData = (PxU8 *)PX_ALLOC(h.mItemSize, PX_DEBUG_EXP("FrameItemSize")); mFileBuffer->seekRead(h.mSeekLocation); PxU32 bcount = mFileBuffer->read(mData,h.mItemSize); if ( bcount == h.mItemSize ) { PxU32 index = 0; const PxU8 *scan = mData; while ( index < h.mItemCount ) { PrimitiveBatch b; const PxU32 *uscan = (const PxU32 *)scan; b.mPrimitiveType = uscan[0]; b.mPrimitiveCount = uscan[1]; b.mPrimitiveIndex = index; mPrimitiveBatch.pushBack(b); uscan+=2; scan = (const PxU8 *)uscan; for (PxU32 i=0; i<b.mPrimitiveCount; i++) { const DebugPrimitive *prim = (const DebugPrimitive *)scan; PX_ASSERT( prim->mCommand >= 0 && prim->mCommand < DebugCommand::LAST ); mPrimitives[i+index] = prim; PxU32 plen = DebugCommand::getPrimtiveSize(*prim); scan+=plen; } index+=b.mPrimitiveCount; } } else { reset(); } } }
void VisualDebugger::updatePvdProperties(const PxHeightField* heightField) { PVD::PvdCommLayerError error; mPvdConnectionHelper.addPropertyGroupProperty(HeightFieldProp::NumRows, heightField->getNbRows()); mPvdConnectionHelper.addPropertyGroupProperty(HeightFieldProp::NumColumns, heightField->getNbColumns()); mPvdConnectionHelper.addPropertyGroupProperty(HeightFieldProp::HeightFieldFormat, PVD::createEnumerationValue(heightField->getFormat())); mPvdConnectionHelper.addPropertyGroupProperty(HeightFieldProp::Thickness, heightField->getThickness()); mPvdConnectionHelper.addPropertyGroupProperty(HeightFieldProp::ConvexEdgeThreshold, heightField->getConvexEdgeThreshold()); mPvdConnectionHelper.addPropertyGroupProperty(HeightFieldProp::Flags, PVD::createBitflag(heightField->getFlags())); error = mPvdConnectionHelper.sendSinglePropertyGroup(mPvdConnection, PX_PROFILE_POINTER_TO_U64(heightField), PvdClassKeys::HeightField); // samples array { PxU32 nbRows = heightField->getNbRows(); PxU32 nbCols = heightField->getNbColumns(); PxU8* samplesPtr = (PxU8*)PX_ALLOC(nbCols*nbRows*sizeof(PxHeightFieldSample)); heightField->saveCells(samplesPtr, nbRows*nbCols*sizeof(PxHeightFieldSample)); PxU32 sampleStride = heightField->getSampleStride(); PxU32 numSamples = nbCols * nbRows; error = PvdConnectionHelper::sendSingleElementArrayProperty(mPvdConnection, PX_PROFILE_POINTER_TO_U64(heightField), HeightFieldProp::Samples , HeightFieldSampleArrayProp::Element, PVD::PvdCommLayerDatatype::HeightFieldSample , samplesPtr, sampleStride, numSamples); PX_FREE_AND_RESET(samplesPtr); } PX_ASSERT(error == PVD::PvdCommLayerError::None); }
ReadWriteLock::ReadWriteLock() { mImpl = reinterpret_cast<ReadWriteLockImpl *>(PX_ALLOC(sizeof(ReadWriteLockImpl), PX_DEBUG_EXP("ReadWriteLockImpl"))); PX_PLACEMENT_NEW(mImpl, ReadWriteLockImpl); mImpl->readerCounter = 0; }
void readNextRemoteCommand(void) { if ( mPlaybackRemoteCommands == NULL ) return; mPlaybackRemoteCommand.release(); // release previous command mPlaybackRemoteCommand.mFrameNumber = mPlaybackRemoteCommands->readDword(); if ( mPlaybackRemoteCommand.mFrameNumber == 0 ) { mPlaybackRemoteCommand.release(); delete mPlaybackRemoteCommands; mPlaybackRemoteCommands = NULL; } else { mPlaybackRemoteCommand.mArgc = mPlaybackRemoteCommands->readDword(); for (uint32_t i=0; i<mPlaybackRemoteCommand.mArgc; i++) { uint32_t len = mPlaybackRemoteCommands->readDword(); mPlaybackRemoteCommand.mArgv[i] = static_cast<const char *>(PX_ALLOC(len,"PlaybackRemoteCommand")); uint32_t rbytes = mPlaybackRemoteCommands->read(reinterpret_cast<void *>(const_cast<char*>(mPlaybackRemoteCommand.mArgv[i])),len); if ( rbytes != len ) { mPlaybackRemoteCommand.release(); delete mPlaybackRemoteCommands; mPlaybackRemoteCommands = NULL; } } } }
D3D9RenderInstanceBuffer::D3D9RenderInstanceBuffer(IDirect3DDevice9 &d3dDevice, const RenderInstanceBufferDesc &desc) : RenderInstanceBuffer(desc) #if RENDERER_INSTANCING ,m_d3dDevice(d3dDevice) #endif { #if RENDERER_INSTANCING m_d3dVertexBuffer = 0; #endif m_usage = 0; m_pool = D3DPOOL_MANAGED; m_bufferSize = (UINT)(desc.maxInstances * m_stride); #if RENDERER_ENABLE_DYNAMIC_VB_POOLS if(desc.hint==RenderInstanceBuffer::HINT_DYNAMIC) { m_usage = D3DUSAGE_DYNAMIC; m_pool = D3DPOOL_DEFAULT; } #endif onDeviceReset(); #if RENDERER_INSTANCING if(m_d3dVertexBuffer) { m_maxInstances = desc.maxInstances; } #else m_maxInstances = desc.maxInstances; mInstanceBuffer = PX_ALLOC(m_maxInstances*m_stride); #endif }
PxVehicleDriveNW* PxVehicleDriveNW::allocate(const PxU32 numWheels) { PX_CHECK_AND_RETURN_NULL(numWheels>0, "Cars with zero wheels are illegal"); PX_CHECK_AND_RETURN_NULL(gToleranceScaleLength > 0, "PxVehicleDriveNW::allocate - need to call PxInitVehicleSDK"); //Compute the bytes needed. const PxU32 byteSize = sizeof(PxVehicleDriveNW) + PxVehicleDrive::computeByteSize(numWheels); //Allocate the memory. PxVehicleDriveNW* veh = static_cast<PxVehicleDriveNW*>(PX_ALLOC(byteSize, "PxVehicleDriveNW")); Cm::markSerializedMem(veh, byteSize); new(veh) PxVehicleDriveNW(); //Patch up the pointers. PxU8* ptr = reinterpret_cast<PxU8*>(veh) + sizeof(PxVehicleDriveNW); ptr=PxVehicleDrive::patchupPointers(numWheels, veh, ptr); //Initialise veh->init(numWheels); //Set the vehicle type. veh->mType = PxVehicleTypes::eDRIVENW; return veh; }
PxVehicleNoDrive* PxVehicleNoDrive::allocate(const PxU32 numWheels) { PX_CHECK_AND_RETURN_NULL(numWheels>0, "Cars with zero wheels are illegal"); //Compute the bytes needed. const PxU32 numWheels4 = (((numWheels + 3) & ~3) >> 2); const PxU32 inputByteSize16 = sizeof(PxReal)*numWheels4*4; const PxU32 byteSize = sizeof(PxVehicleNoDrive) + 3*inputByteSize16 + PxVehicleWheels::computeByteSize(numWheels4); //Allocate the memory. PxVehicleNoDrive* veh = (PxVehicleNoDrive*)PX_ALLOC(byteSize, PX_DEBUG_EXP("PxVehicleNoDrive")); Cm::markSerializedMem(veh, byteSize); new(veh) PxVehicleNoDrive(); //Patch up the pointers. PxU8* ptr = (PxU8*)veh + sizeof(PxVehicleNoDrive); ptr=PxVehicleWheels::patchupPointers(veh,ptr,numWheels4,numWheels); veh->mSteerAngles = (PxReal*)ptr; ptr+=inputByteSize16; veh->mDriveTorques = (PxReal*)ptr; ptr+=inputByteSize16; veh->mBrakeTorques = (PxReal*)ptr; ptr+=inputByteSize16; PxMemZero(veh->mSteerAngles, inputByteSize16); PxMemZero(veh->mDriveTorques, inputByteSize16); PxMemZero(veh->mBrakeTorques, inputByteSize16); //Set the vehicle type. veh->mType = PxVehicleTypes::eNODRIVE; return veh; }
Thread::Thread() { mImpl = (ThreadImpl *)PX_ALLOC(sizeof(ThreadImpl)); mImpl->thread = NULL; mImpl->state = ThreadImpl::NotStarted; mImpl->quitNow = 0; }
MemoryMappedFile::MemoryMappedFile(const char *mappingObject,unsigned int mapSize) { mImpl = (MemoryMappedFileImpl *)PX_ALLOC(sizeof(MemoryMappedFileImpl), PX_DEBUG_EXP("MemoryMappedFileImpl")); mImpl->mHeader = 0; PX_ASSERT(0); // not implemented }
Thread::Thread(ExecuteFn fn, void *arg) { mImpl = (ThreadImpl *)PX_ALLOC(sizeof(ThreadImpl)); mImpl->thread = NULL; mImpl->state = ThreadImpl::NotStarted; mImpl->quitNow = 0; mImpl->fn = fn; mImpl->arg = arg; start(0); }
ResID ApexResourceProvider::NameSpace::getOrCreateID(const char* &name, const char* NSName) { /* Hash Table Entry: | nextEntry* | ResID | name | */ uint16_t h = genHash(name); const char* entry = hash[h]; while (entry) { entryHeader* hdr = (entryHeader*) entry; const char* entryName = entry + sizeof(entryHeader); if (mArp->stringsMatch(name, entryName)) { name = entryName; return hdr->id; } entry = hdr->nextEntry; } size_t len = strlen(name); size_t bufsize = len + 1 + sizeof(entryHeader); char* newEntry = (char*) PX_ALLOC(bufsize, PX_DEBUG_EXP("ApexResourceProvider::NameSpace::getOrCreateID")); if (newEntry) { #if defined(WIN32) strncpy_s(newEntry + sizeof(entryHeader), bufsize - sizeof(entryHeader), name, len); #else strcpy(newEntry + sizeof(entryHeader), name); #endif entryHeader* hdr = (entryHeader*) newEntry; hdr->nextEntry = hash[h]; hdr->id = mArp->mResources.size(); resource res; res.ptr = (void*) UnknownValue; res.valueIsSet = false; res.name = newEntry + sizeof(entryHeader); res.nameSpace = NSName; res.refCount = 0; res.usedGetResource = 0; mArp->mResources.pushBack(res); hash[h] = (const char*) newEntry; name = res.name; return hdr->id; } return INVALID_RESOURCE_ID; }
SampleVehicleSceneQueryData* SampleVehicleSceneQueryData::allocate(const PxU32 maxNumWheels) { const PxU32 size = sizeof(SampleVehicleSceneQueryData) + sizeof(PxRaycastQueryResult)*maxNumWheels + sizeof(PxRaycastHit)*maxNumWheels; SampleVehicleSceneQueryData* sqData = (SampleVehicleSceneQueryData*)PX_ALLOC(size, PX_DEBUG_EXP("PxVehicleNWSceneQueryData")); sqData->init(); PxU8* ptr = (PxU8*) sqData; ptr += sizeof(SampleVehicleSceneQueryData); sqData->mSqResults = (PxRaycastQueryResult*)ptr; ptr += sizeof(PxRaycastQueryResult)*maxNumWheels; sqData->mSqHitBuffer = (PxRaycastHit*)ptr; ptr += sizeof(PxRaycastHit)*maxNumWheels; sqData->mNumQueries = maxNumWheels; return sqData; }
ApexResourceProvider::NameSpace::NameSpace(ApexResourceProvider* arp, ResID nsid, bool releaseAtExit, const char* nameSpace) : mReleaseAtExit(releaseAtExit), mArp(arp), mId(nsid) { memset(hash, 0, sizeof(hash)); mNameSpace = 0; if (nameSpace) { uint32_t len = (uint32_t) strlen(nameSpace); mNameSpace = (char*)PX_ALLOC(len + 1, PX_DEBUG_EXP("ApexResourceProvider::NameSpace")); memcpy(mNameSpace, nameSpace, len + 1); } }
DefaultCpuDispatcher::DefaultCpuDispatcher(PxU32 numThreads, PxU32* affinityMasks) : mQueueEntryPool(TASK_QUEUE_ENTRY_POOL_SIZE), mNumThreads(numThreads), mShuttingDown(false) { PxU32 defaultAffinityMask = 0; if (!affinityMasks) { defaultAffinityMask = getAffinityMask(numThreads); } // initialize threads first, then start mWorkerThreads = reinterpret_cast<CpuWorkerThread*>(PX_ALLOC(numThreads * sizeof(CpuWorkerThread), PX_DEBUG_EXP("CpuWorkerThread"))); if (mWorkerThreads) { for (PxU32 i = 0; i < numThreads; ++i) { PX_PLACEMENT_NEW(mWorkerThreads + i, CpuWorkerThread)(); mWorkerThreads[i].initialize(this); } for (PxU32 i = 0; i < numThreads; ++i) { mWorkerThreads[i].start(shdfnd::Thread::getDefaultStackSize()); if (affinityMasks) { mWorkerThreads[i].setAffinityMask(affinityMasks[i]); } else { mWorkerThreads[i].setAffinityMask(defaultAffinityMask); #ifdef PX_X360 defaultAffinityMask &= defaultAffinityMask - 1; // clear lowest bit #endif } char threadName[32]; string::sprintf_s(threadName, 32, "PxWorker%02d", i); mWorkerThreads[i].setName(threadName); } } else { mNumThreads = 0; } }
PxVehicleDriveNW* PxVehicleDriveNW::allocate(const PxU32 numWheels) { PX_CHECK_AND_RETURN_NULL(numWheels>0, "Cars with zero wheels are illegal"); //Compute the bytes needed. const PxU32 numWheels4 = (((numWheels + 3) & ~3) >> 2); const PxU32 byteSize = sizeof(PxVehicleDriveNW) + PxVehicleDrive::computeByteSize(numWheels4); //Allocate the memory. PxVehicleDriveNW* veh = (PxVehicleDriveNW*)PX_ALLOC(byteSize, PX_DEBUG_EXP("PxVehicleDriveNW")); Cm::markSerializedMem(veh, byteSize); new(veh) PxVehicleDriveNW(); //Patch up the pointers. PxU8* ptr = (PxU8*)veh + sizeof(PxVehicleDriveNW); ptr=PxVehicleDrive::patchupPointers(veh,ptr,numWheels4,numWheels); //Set the vehicle type. veh->mType = PxVehicleTypes::eDRIVENW; return veh; }
PxVehicleDriveTank* PxVehicleDriveTank::allocate(const PxU32 numWheels) { PX_CHECK_AND_RETURN_NULL(numWheels>0, "Cars with zero wheels are illegal"); //Compute the bytes needed. const PxU32 numWheels4 = (((numWheels + 3) & ~3) >> 2); const PxU32 byteSize = sizeof(PxVehicleDriveTank) + + PxVehicleDrive::computeByteSize(numWheels4); //Allocate the memory. PxVehicleDriveTank* veh = (PxVehicleDriveTank*)PX_ALLOC(byteSize, PX_DEBUG_EXP("PxVehicleDriveTank")); //Patch up the pointers. PxU8* ptr = (PxU8*)veh + sizeof(PxVehicleDriveTank); PxVehicleDrive::patchupPointers(veh,ptr,numWheels4,numWheels); //Set the vehicle type. veh->mType = eVEHICLE_TYPE_DRIVETANK; //Set the default drive model. veh->mDriveModel = eDRIVE_MODEL_STANDARD; return veh; }
PxVehicleDrivableSurfaceToTireFrictionPairs* PxVehicleDrivableSurfaceToTireFrictionPairs::create (const PxU32 maxNumTireTypes, const PxU32 maxNumSurfaceTypes, const PxMaterial** drivableSurfaceMaterials, const PxVehicleDrivableSurfaceType* drivableSurfaceTypes) { PX_CHECK_AND_RETURN_VAL(maxNumSurfaceTypes < eMAX_NUM_SURFACE_TYPES, "maxNumSurfaceTypes must be less than eMAX_NUM_SURFACE_TYPES", NULL); PxU32 byteSize = ((sizeof(PxU32)*(maxNumTireTypes*maxNumSurfaceTypes) + 15) & ~15); byteSize += ((sizeof(PxMaterial*)*maxNumSurfaceTypes + 15) & ~15); byteSize += ((sizeof(PxVehicleDrivableSurfaceType)*maxNumSurfaceTypes + 15) & ~15); byteSize += ((sizeof(PxVehicleDrivableSurfaceToTireFrictionPairs) + 15) & ~ 15); PxU8* ptr = (PxU8*)PX_ALLOC(byteSize, PX_DEBUG_EXP("PxVehicleDrivableSurfaceToTireFrictionPairs")); PxVehicleDrivableSurfaceToTireFrictionPairs* pairs = (PxVehicleDrivableSurfaceToTireFrictionPairs*)ptr; ptr += ((sizeof(PxVehicleDrivableSurfaceToTireFrictionPairs) + 15) & ~ 15); pairs->mPairs = (PxReal*)ptr; ptr += ((sizeof(PxU32)*(maxNumTireTypes*maxNumSurfaceTypes) + 15) & ~15); pairs->mDrivableSurfaceMaterials = (const PxMaterial**)ptr; ptr += ((sizeof(PxMaterial*)*maxNumSurfaceTypes + 15) & ~15); pairs->mDrivableSurfaceTypes = (PxVehicleDrivableSurfaceType*)ptr; ptr += ((sizeof(PxVehicleDrivableSurfaceType)*maxNumSurfaceTypes +15) & ~15); for(PxU32 i=0;i<maxNumSurfaceTypes;i++) { pairs->mDrivableSurfaceTypes[i] = drivableSurfaceTypes[i]; pairs->mDrivableSurfaceMaterials[i] = drivableSurfaceMaterials[i]; } for(PxU32 i=0;i<maxNumTireTypes*maxNumSurfaceTypes;i++) { pairs->mPairs[i]=1.0f; } pairs->mNumTireTypes=maxNumTireTypes; pairs->mNumSurfaceTypes=maxNumSurfaceTypes; return pairs; }
void PxsFluidDynamics::adjustTempBuffers(PxU32 count) { PX_ASSERT(count <= PXS_FLUID_MAX_PARALLEL_TASKS_SPH); PX_ASSERT(mNumTempBuffers <= PXS_FLUID_MAX_PARALLEL_TASKS_SPH); Ps::AlignedAllocator<16, Ps::ReflectionAllocator<char> > align16; // shrink for (PxU32 i = count; i < mNumTempBuffers; ++i) { PxsFluidDynamicsTempBuffers& tempBuffers = mTempBuffers[i]; if (tempBuffers.indexStream) PX_FREE_AND_RESET(tempBuffers.indexStream); if (tempBuffers.hashKeys) PX_FREE_AND_RESET(tempBuffers.hashKeys); if (tempBuffers.mergedIndices) PX_FREE_AND_RESET(tempBuffers.mergedIndices); if (tempBuffers.indicesSubpacketA) PX_FREE_AND_RESET(tempBuffers.indicesSubpacketA); if (tempBuffers.indicesSubpacketB) PX_FREE_AND_RESET(tempBuffers.indicesSubpacketB); if (tempBuffers.cellHashTableSubpacketB) PX_FREE_AND_RESET(tempBuffers.cellHashTableSubpacketB); if (tempBuffers.cellHashTableSubpacketA) PX_FREE_AND_RESET(tempBuffers.cellHashTableSubpacketA); if (tempBuffers.simdPositionsSubpacket) { align16.deallocate(tempBuffers.simdPositionsSubpacket); tempBuffers.simdPositionsSubpacket = NULL; } if (tempBuffers.mergedHaloRegions) { align16.deallocate(tempBuffers.mergedHaloRegions); tempBuffers.mergedHaloRegions = NULL; } } // growing for (PxU32 i = mNumTempBuffers; i < count; ++i) { PxsFluidDynamicsTempBuffers& tempBuffers = mTempBuffers[i]; // Make sure the number of hash buckets is a power of 2 (requirement for the used hash function) tempBuffers.cellHashMaxSize = Ps::nextPowerOfTwo((PXS_FLUID_SUBPACKET_PARTICLE_LIMIT_FORCE_DENSITY + 1)); // Local hash tables for particle cells (for two subpackets A and B). tempBuffers.cellHashTableSubpacketA = (PxsParticleCell*)PX_ALLOC(tempBuffers.cellHashMaxSize*sizeof(PxsParticleCell), PX_DEBUG_EXP("PxsParticleCell")); tempBuffers.cellHashTableSubpacketB = (PxsParticleCell*)PX_ALLOC(tempBuffers.cellHashMaxSize*sizeof(PxsParticleCell), PX_DEBUG_EXP("PxsParticleCell")); // Particle index lists for local hash of particle cells (for two subpackets A and B). tempBuffers.indicesSubpacketA = (PxU32*)PX_ALLOC(PXS_FLUID_SUBPACKET_PARTICLE_LIMIT_FORCE_DENSITY*sizeof(PxU32), PX_DEBUG_EXP("Subpacket indices")); tempBuffers.indicesSubpacketB = (PxU32*)PX_ALLOC(PXS_FLUID_SUBPACKET_PARTICLE_LIMIT_FORCE_DENSITY*sizeof(PxU32), PX_DEBUG_EXP("Subpacket indices")); tempBuffers.mergedIndices = (PxU32*)PX_ALLOC(PXS_FLUID_SUBPACKET_PARTICLE_LIMIT_FORCE_DENSITY*sizeof(PxU32), PX_DEBUG_EXP("Subpacket merged indices")); tempBuffers.mergedHaloRegions = (PxsFluidParticle*) align16.allocate(PXS_FLUID_SUBPACKET_PARTICLE_LIMIT_FORCE_DENSITY*sizeof(PxsFluidParticle), __FILE__, __LINE__); tempBuffers.hashKeys = (PxU16*)PX_ALLOC(PXS_FLUID_SUBPACKET_PARTICLE_LIMIT_FORCE_DENSITY*sizeof(PxU16), PX_DEBUG_EXP("Subpacket hashKeys")); // SIMD buffer for storing intermediate particle positions of up to a subpacket size. // Ceil up to multiple of four + 4 for save unrolling. // For 4 particles we need three Vec4V. PxU32 paddedSubPacketMax = ((PXS_FLUID_SUBPACKET_PARTICLE_LIMIT_FORCE_DENSITY + 3) & ~0x3) + 4; tempBuffers.simdPositionsSubpacket = (PxU8*)align16.allocate(3*(paddedSubPacketMax / 4)*sizeof(Vec4V), __FILE__, __LINE__); tempBuffers.indexStream = (PxU32*)PX_ALLOC(MAX_INDEX_STREAM_SIZE*sizeof(PxU32), PX_DEBUG_EXP("indexStream")); tempBuffers.orderedIndicesSubpacket = sOrderedIndexTable.indices; } mNumTempBuffers = count; }
void Gu::TriangleMesh::debugVisualize( Cm::RenderOutput& out, const PxTransform& pose, const PxMeshScale& scaling, const PxBounds3& cullbox, const PxU64 mask, const PxReal fscale, const PxU32 numMaterials) const { PX_UNUSED(numMaterials); //bool cscale = !!(mask & ((PxU64)1 << PxVisualizationParameter::eCULL_BOX)); const PxU64 cullBoxMask = PxU64(1) << PxVisualizationParameter::eCULL_BOX; bool cscale = ((mask & cullBoxMask) == cullBoxMask); const PxMat44 midt(PxIdentity); const Cm::Matrix34 absPose(PxMat33(pose.q) * scaling.toMat33(), pose.p); PxU32 nbTriangles = getNbTrianglesFast(); const PxU32 nbVertices = getNbVerticesFast(); const PxVec3* vertices = getVerticesFast(); const void* indices = getTrianglesFast(); const PxDebugColor::Enum colors[] = { PxDebugColor::eARGB_BLACK, PxDebugColor::eARGB_RED, PxDebugColor::eARGB_GREEN, PxDebugColor::eARGB_BLUE, PxDebugColor::eARGB_YELLOW, PxDebugColor::eARGB_MAGENTA, PxDebugColor::eARGB_CYAN, PxDebugColor::eARGB_WHITE, PxDebugColor::eARGB_GREY, PxDebugColor::eARGB_DARKRED, PxDebugColor::eARGB_DARKGREEN, PxDebugColor::eARGB_DARKBLUE, }; const PxU32 colorCount = sizeof(colors)/sizeof(PxDebugColor::Enum); if(cscale) { const Gu::Box worldBox( (cullbox.maximum + cullbox.minimum)*0.5f, (cullbox.maximum - cullbox.minimum)*0.5f, PxMat33(PxIdentity)); // PT: TODO: use the callback version here to avoid allocating this huge array PxU32* results = reinterpret_cast<PxU32*>(PX_ALLOC_TEMP(sizeof(PxU32)*nbTriangles, "tmp triangle indices")); LimitedResults limitedResults(results, nbTriangles, 0); Midphase::intersectBoxVsMesh(worldBox, *this, pose, scaling, &limitedResults); nbTriangles = limitedResults.mNbResults; if (fscale) { const PxU32 fcolor = PxU32(PxDebugColor::eARGB_DARKRED); for (PxU32 i=0; i<nbTriangles; i++) { const PxU32 index = results[i]; PxVec3 wp[3]; getTriangle(*this, index, wp, vertices, indices, absPose, has16BitIndices()); const PxVec3 center = (wp[0] + wp[1] + wp[2]) / 3.0f; PxVec3 normal = (wp[0] - wp[1]).cross(wp[0] - wp[2]); PX_ASSERT(!normal.isZero()); normal = normal.getNormalized(); out << midt << fcolor << Cm::DebugArrow(center, normal * fscale); } } if (mask & (PxU64(1) << PxVisualizationParameter::eCOLLISION_SHAPES)) { const PxU32 scolor = PxU32(PxDebugColor::eARGB_MAGENTA); out << midt << scolor; // PT: no need to output this for each segment! PxDebugLine* segments = out.reserveSegments(nbTriangles*3); for(PxU32 i=0; i<nbTriangles; i++) { const PxU32 index = results[i]; PxVec3 wp[3]; getTriangle(*this, index, wp, vertices, indices, absPose, has16BitIndices()); segments[0] = PxDebugLine(wp[0], wp[1], scolor); segments[1] = PxDebugLine(wp[1], wp[2], scolor); segments[2] = PxDebugLine(wp[2], wp[0], scolor); segments+=3; } } if ((mask & (PxU64(1) << PxVisualizationParameter::eCOLLISION_EDGES)) && mExtraTrigData) visualizeActiveEdges(out, *this, nbTriangles, results, absPose, midt); PX_FREE(results); } else { if (fscale) { const PxU32 fcolor = PxU32(PxDebugColor::eARGB_DARKRED); for (PxU32 i=0; i<nbTriangles; i++) { PxVec3 wp[3]; getTriangle(*this, i, wp, vertices, indices, absPose, has16BitIndices()); const PxVec3 center = (wp[0] + wp[1] + wp[2]) / 3.0f; PxVec3 normal = (wp[0] - wp[1]).cross(wp[0] - wp[2]); PX_ASSERT(!normal.isZero()); normal = normal.getNormalized(); out << midt << fcolor << Cm::DebugArrow(center, normal * fscale); } } if (mask & (PxU64(1) << PxVisualizationParameter::eCOLLISION_SHAPES)) { PxU32 scolor = PxU32(PxDebugColor::eARGB_MAGENTA); out << midt << scolor; // PT: no need to output this for each segment! PxVec3* transformed = reinterpret_cast<PxVec3*>(PX_ALLOC(sizeof(PxVec3)*nbVertices, "PxVec3")); for(PxU32 i=0;i<nbVertices;i++) transformed[i] = absPose.transform(vertices[i]); PxDebugLine* segments = out.reserveSegments(nbTriangles*3); for (PxU32 i=0; i<nbTriangles; i++) { PxVec3 wp[3]; getTriangle(*this, i, wp, transformed, indices, has16BitIndices()); const PxU32 localMaterialIndex = getTriangleMaterialIndex(i); scolor = colors[localMaterialIndex % colorCount]; segments[0] = PxDebugLine(wp[0], wp[1], scolor); segments[1] = PxDebugLine(wp[1], wp[2], scolor); segments[2] = PxDebugLine(wp[2], wp[0], scolor); segments+=3; } PX_FREE(transformed); } if ((mask & (PxU64(1) << PxVisualizationParameter::eCOLLISION_EDGES)) && mExtraTrigData) visualizeActiveEdges(out, *this, nbTriangles, NULL, absPose, midt); } }