// // 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-2021 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 "SampleVehicle.h" #include "RenderPhysX3Debug.h" #include "PxRigidDynamic.h" #include "SampleVehicle_VehicleManager.h" using namespace SampleRenderer; // PT: this file contains the part of SampleVehicle dealing with cars' debug rendering void SampleVehicle::drawWheels() { PxSceneReadLock scopedLock(*mScene); const RendererColor colorPurple(255, 0, 255); for(PxU32 i=0;igetRigidDynamicActor(); PxShape* shapeBuffer[PX_MAX_NB_WHEELS]; actor->getShapes(shapeBuffer,veh->mWheelsSimData.getNbWheels()); const PxTransform vehGlobalPose=actor->getGlobalPose(); const PxU32 numWheels=veh->mWheelsSimData.getNbWheels(); for(PxU32 j=0;jgetLocalPose()); const PxF32 wheelRadius=veh->mWheelsSimData.getWheelData(j).mRadius; const PxF32 wheelHalfWidth=veh->mWheelsSimData.getWheelData(j).mWidth*0.5f; PxVec3 offset=wheelTransform.q.getBasisVector0()*wheelHalfWidth; offset*= (veh->mWheelsSimData.getWheelCentreOffset(j).x > 0) ? 1.0f : -1.0f; const PxVec3 arrow=wheelTransform.rotate(PxVec3(0,0,1)); getDebugRenderer()->addLine(wheelTransform.p+offset, wheelTransform.p+offset+arrow*wheelRadius, colorPurple); } } } void SampleVehicle::drawVehicleDebug() { PxSceneReadLock scopedLock(*mScene); const RendererColor colorColl(255, 0, 0); const RendererColor colorCol2(0, 255, 0); const RendererColor colorCol3(0, 0, 255); #if PX_DEBUG_VEHICLE_ON const PxVec3* tireForceAppPoints=NULL; const PxVec3* suspForceAppPoints=NULL; switch(mPlayerVehicleType) { case ePLAYER_VEHICLE_TYPE_VEHICLE4W: case ePLAYER_VEHICLE_TYPE_TANK4W: tireForceAppPoints=mTelemetryData4W->getTireforceAppPoints(); suspForceAppPoints=mTelemetryData4W->getSuspforceAppPoints(); break; case ePLAYER_VEHICLE_TYPE_VEHICLE6W: case ePLAYER_VEHICLE_TYPE_TANK6W: tireForceAppPoints=mTelemetryData6W->getTireforceAppPoints(); suspForceAppPoints=mTelemetryData6W->getSuspforceAppPoints(); break; default: PX_ASSERT(false); break; } #endif const PxVehicleWheels& vehicle4W=*mVehicleManager.getVehicle(mPlayerVehicle); const PxVehicleWheelQueryResult& vehicleWheelQueryResults=mVehicleManager.getVehicleWheelQueryResults(mPlayerVehicle); const PxRigidDynamic* actor=vehicle4W.getRigidDynamicActor(); const PxU32 numWheels=vehicle4W.mWheelsSimData.getNbWheels(); PxVec3 v[8]; PxVec3 w[8]; PxF32 l[8]; for(PxU32 i=0;igetGlobalPose().transform(actor->getCMassLocalPose()); const PxVec3 dirs[3]={t.rotate(PxVec3(1,0,0)),t.rotate(PxVec3(0,1,0)),t.rotate(PxVec3(0,0,1))}; getDebugRenderer()->addLine(t.p, t.p + dirs[0]*4.0f, colorColl); getDebugRenderer()->addLine(t.p, t.p + dirs[1]*4.0f, colorColl); getDebugRenderer()->addLine(t.p, t.p + dirs[2]*4.0f, colorColl); for(PxU32 j=0;jaddLine(v[j], v[j]+w[j]*l[j], colorColl); #if PX_DEBUG_VEHICLE_ON //Draw all tire force app points. const PxVec3& appPoint = tireForceAppPoints[j]; getDebugRenderer()->addLine(appPoint - dirs[0], appPoint + dirs[0], colorCol2); getDebugRenderer()->addLine(appPoint - dirs[2], appPoint + dirs[2], colorCol2); //Draw all susp force app points. const PxVec3& appPoint2 = suspForceAppPoints[j]; getDebugRenderer()->addLine(appPoint2 - dirs[0], appPoint2 + dirs[0], colorCol3); getDebugRenderer()->addLine(appPoint2 - dirs[2], appPoint2 + dirs[2], colorCol3); #endif } } static void drawBox2D(Renderer* renderer, PxF32 minX, PxF32 maxX, PxF32 minY, PxF32 maxY, const RendererColor& color, PxF32 alpha) { ScreenQuad sq; sq.mX0 = minX; sq.mY0 = 1.0f - minY; sq.mX1 = maxX; sq.mY1 = 1.0f - maxY; sq.mLeftUpColor = color; sq.mRightUpColor = color; sq.mLeftDownColor = color; sq.mRightDownColor = color; sq.mAlpha = alpha; renderer->drawScreenQuad(sq); } static void print(Renderer* renderer, PxF32 x, PxF32 y, PxF32 scale_, const char* text) { PxU32 width, height; renderer->getWindowSize(width, height); y = 1.0f - y; const PxReal scale = scale_*20.0f; const PxReal shadowOffset = 6.0f; const RendererColor textColor(255, 255, 255, 255); renderer->print(PxU32(x*PxF32(width)), PxU32(y*PxF32(height)), text, scale, shadowOffset, textColor); } void SampleVehicle::drawHud() { const PxVehicleWheels& focusVehicle = *mVehicleManager.getVehicle(mPlayerVehicle); PxVehicleDriveDynData* driveDynData=NULL; PxVehicleDriveSimData* driveSimData=NULL; switch(focusVehicle.getVehicleType()) { case PxVehicleTypes::eDRIVE4W: { PxVehicleDrive4W& vehDrive4W=(PxVehicleDrive4W&)focusVehicle; driveDynData=&vehDrive4W.mDriveDynData; driveSimData=&vehDrive4W.mDriveSimData; } break; case PxVehicleTypes::eDRIVENW: { PxVehicleDriveNW& vehDriveNW=(PxVehicleDriveNW&)focusVehicle; driveDynData=&vehDriveNW.mDriveDynData; driveSimData=&vehDriveNW.mDriveSimData; } break; case PxVehicleTypes::eDRIVETANK: { PxVehicleDriveTank& vehDriveTank=(PxVehicleDriveTank&)focusVehicle; driveDynData=&vehDriveTank.mDriveDynData; driveSimData=&vehDriveTank.mDriveSimData; } break; default: PX_ASSERT(false); break; } const PxU32 currentGear=driveDynData->getCurrentGear(); const PxF32 vz=mForwardSpeedHud*3.6f; const PxF32 revs=driveDynData->getEngineRotationSpeed(); const PxF32 maxRevs=driveSimData->getEngineData().mMaxOmega*60*0.5f/PxPi;//Convert from radians per second to rpm const PxF32 invMaxRevs=driveSimData->getEngineData().getRecipMaxOmega(); //Draw gears and speed. const PxF32 x=0.5f; const PxF32 y=0.18f; const PxF32 length=0.1f; const PxF32 textheight=0.02f; Renderer* renderer = getRenderer(); drawBox2D(renderer, x-length-textheight, x+length+textheight, y, y+length+textheight, RendererColor(255, 255, 255), 0.5f); //Gear char gear[PxVehicleGearsData::eGEARSRATIO_COUNT][64]= { "R","N","1","2","3","4","5" }; print(renderer, x-0.25f*textheight, y+0.02f, 0.02f, gear[currentGear]); //Speed char speed[64]; sprintf(speed, "%1.0f %s", PxAbs(vz), "kmph"); print(renderer, x-textheight, y+length-textheight, textheight, speed); //Revs { const PxF32 xy[4]={x, 1.0f-y, x-length, 1.0f-(y+length)}; renderer->drawLines2D(2, xy, RendererColor(0, 0, 255)); char buffer[64]; sprintf(buffer, "%d \n", 0); print(renderer, x-length, y+length, textheight, buffer); } { const PxF32 xy[4]={x, 1.0f-y, x+length, 1.0f-(y+length)}; renderer->drawLines2D(2, xy, RendererColor(0, 0, 255)); char buffer[64]; sprintf(buffer, "%1.0f \n", maxRevs); print(renderer, x+length-2*textheight, y+length, textheight, buffer); } { const PxF32 alpha=revs*invMaxRevs; const PxF32 dx=-(1.0f-alpha)*length + alpha*length; const PxF32 xy[4]={x, 1.0f-y, x+dx, 1.0f-(y+length)}; renderer->drawLines2D(2, xy, RendererColor(255, 0, 0)); } } #if PX_DEBUG_VEHICLE_ON static PX_FORCE_INLINE RendererColor getColor(const PxVec3& c) { return RendererColor(PxU8(c.x), PxU8(c.y), PxU8(c.z)); } static PX_FORCE_INLINE void convertColors(const PxVec3* src, RendererColor* dst) { for(PxU32 i=0;idrawLines2D(PxVehicleGraph::eMAX_NB_SAMPLES, xy, rendererColor); print(renderer, xMin,yMax-0.02f, 0.02f, title); const PxU32 tireType=tireTypes[i]; const PxU32 tireSurfaceType=surfaceTypes[i]; if (PxVehicleDrivableSurfaceType::eSURFACE_TYPE_UNKNOWN!=tireSurfaceType) { const char* surfaceType= SurfaceTypeNames::getName(tireSurfaceType); const PxF32 friction=TireFrictionMultipliers::getValue(tireSurfaceType, tireType); char surfaceDetails[64]; sprintf(surfaceDetails, "%s %1.2f \n", surfaceType, friction); print(renderer, xMin+0.1f, yMax-0.12f, 0.02f, surfaceDetails); } } PxF32 xMin,xMax,yMin,yMax; telemetryData.getEngineGraph().getBackgroundCoords(xMin,yMin,xMax,yMax); const PxVec3& backgroundColor=telemetryData.getEngineGraph().getBackgroundColor(); const PxF32 alpha=telemetryData.getEngineGraph().getBackgroundAlpha(); drawBox2D(renderer, xMin,xMax,yMin,yMax, getColor(backgroundColor),alpha); telemetryData.getEngineGraph().computeGraphChannel(activeEngineGraphChannel,xy,color,title); convertY(xy); convertColors(color, rendererColor); renderer->drawLines2D(PxVehicleGraph::eMAX_NB_SAMPLES, xy, rendererColor); print(renderer, xMin,yMax-0.02f,0.02f,title); } #endif //PX_DEBUG_VEHICLE_GRAPH_ON void SampleVehicle::drawGraphsAndPrintTireSurfaceTypes(const PxVehicleWheels& focusVehicle, const PxVehicleWheelQueryResult& focusVehicleWheelQueryResults) { #if PX_DEBUG_VEHICLE_ON PxU32 tireTypes[8]; PxU32 surfaceTypes[8]; const PxU32 numWheels=focusVehicle.mWheelsSimData.getNbWheels(); PX_ASSERT(numWheels<=8); for(PxU32 i=0;i