box2d for java_PhysX和Box2D 性能对比

在多刚体模拟中,Java的Box2D在性能上显著优于PhysX,尤其是在刚体数量较少时,PhysX表现出更高的性能。通过创建和运行100个和250个刚体的测试,Box2D在100万次模拟中的表现更加高效。
摘要由CSDN通过智能技术生成

结论1:简单模拟下 Box2D性能在多刚体上 比PhysX高很多,刚体数量比较少的情况下 PhysX 性能高很多

测试1:

int main(int argc, char** argv)

{

B2_NOT_USED(argc);

B2_NOT_USED(argv);

// Define the gravity vector.

b2Vec2 gravity(0.0f, -9.8f);

// Construct a world object, which will hold and simulate the rigid bodies.

b2World world(gravity);

// Define the ground body.

//b2BodyDef groundBodyDef;

//groundBodyDef.position.Set(0.0f, -10.0f);

// Call the body factory which allocates memory for the ground body

// from a pool and creates the ground box shape (also from a pool).

// The body is also added to the world.

//b2Body* groundBody = world.CreateBody(&groundBodyDef);

// Define the ground box shape.

//b2PolygonShape groundBox;

// The extents are the half-widths of the box.

//groundBox.SetAsBox(50.0f, 10.0f);

// Add the ground fixture to the ground body.

//groundBody->CreateFixture(&groundBox, 0.0f);

// Set the box density to be non-zero, so it will be dynamic.

//fixtureDef.density = 1.0f;

// Override the default friction.

//fixtureDef.friction = 0.3f;

b2Body* body;// = world.CreateBody(&bodyDef);

// Add the shape to the body.

//body->CreateFixture(&fixtureDef);

for (int i = 0; i < 100; i++)

{

// b2Body* body = world.CreateBody(&bodyDef);

// Add the shape to the body.

//body->CreateFixture(&fixtureDef);

}

for (int i = 0; i < 250; i++)

{

// Define the dynamic body. We set its position and call the body factory.

b2BodyDef bodyDef;

bodyDef.type = b2_dynamicBody;

bodyDef.position.Set(0.0f, 0.0f);

// Define another box shape for our dynamic body.

b2PolygonShape dynamicBox;

dynamicBox.SetAsBox(1.0f, 1.0f);

// Define the dynamic body fixture.

b2FixtureDef fixtureDef;

fixtureDef.shape = &dynamicBox;

bodyDef.type = b2_dynamicBody;

body = world.CreateBody(&bodyDef);

bodyDef.position.Set(1.0f, 1.0f*i);

// Add the shape to the body.

body->CreateFixture(&fixtureDef);

//body->ApplyForceToCenter(b2Vec2(10.0f, 0.0f),true);

}

// Prepare for simulation. Typically we use a time step of 1/60 of a

// second (60Hz) and 10 iterations. This provides a high quality simulation

// in most game scenarios.

float32 timeStep = 1.0f / 30.0f;

int32 velocityIterations = 2;

int32 positionIterations = 2;

/*b2RayCastOutput output ;

b2RayCastInput input;

input.maxFraction = 12.0f;

input.p1 = body->GetPosition();

input.p2 = body->GetPosition();

input.p2.x += 1.0f;*/

int t = time(nullptr);

printf("start simulate\n");

// This is our little game loop.

for (int32 i = 0; i < 100; ++i)

{

// Instruct the world to perform a single step of simulation.

// It is generally best to keep the time step and iterations fixed.

world.Step(0.016f, 8, 2);

// Now print the position and angle of the body.

//b2Vec2 position = body->GetPosition();

//float32 angle = body->GetAngle();

//printf("%4.2f %4.2f %4.2f\n", position.x, position.y, angle);

}

cout << time(nullptr) - t <GetLinearVelocity().Length()<GetMass() <

// When the world destructor is called, all bodies and joints are freed. This can

// create orphaned pointers, so be careful about your world management.

system("pause");

return 0;

}

PhysX

int main()

{

PxDefaultAllocator gDefaultAllocatorCallback;

static PxSampleAllocator* gAllocator = new PxSampleAllocator;

//Recording memory allocations is necessary if you want to

//use the memory facilities in PVD effectively. Since PVD isn't necessarily connected

//right away, we add a mechanism that records all outstanding memory allocations and

//forwards them to PVD when it does connect.

//This certainly has a performance and memory profile effect and thus should be used

//only in non-production builds.

bool recordMemoryAllocations = true;

#ifdef RENDERER_ANDROID

const bool useCustomTrackingAllocator = false;

#else

const bool useCustomTrackingAllocator = true;

#endif

PxAllocatorCallback* allocator = &gDefaultAllocatorCallback;

auto mFoundation = PxCreateFoundation(PX_FOUNDATION_VERSION, *allocator, getSampleErrorCallback());

PxTolerancesScale scale;

auto mPvd = physx::PxCreatePvd(*mFoundation);

auto mPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *mFoundation, scale, recordMemoryAllocations, mPvd);

if (!mPhysics)

{

}

if (!PxInitExtensions(*mPhysics, mPvd))

{

}

PxCookingParams params(scale);

params.meshWeldTolerance = 0.001f;

params.meshPreprocessParams = PxMeshPreprocessingFlags(PxMeshPreprocessingFlag::eWELD_VERTICES);

params.buildGPUData = true; //Enable GRB data being produced in cooking.

// setup default material...

auto mMaterial = mPhysics->createMaterial(0.5f, 0.5f, 0.1f);

PxSceneDesc sceneDesc(mPhysics->getTolerancesScale());

sceneDesc.filterShader = PxDefaultSimulationFilterShader;

if (!sceneDesc.cpuDispatcher)

{

automCpuDispatcher = PxDefaultCpuDispatcherCreate(0);

sceneDesc.cpuDispatcher = mCpuDispatcher;

}

sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);

//sceneDesc.flags |= PxSceneFlag::eENABLE_GPU_DYNAMICS;

sceneDesc.flags |= PxSceneFlag::eENABLE_PCM;

//sceneDesc.flags |= PxSceneFlag::eENABLE_AVERAGE_POINT;

sceneDesc.flags |= PxSceneFlag::eENABLE_STABILIZATION;

//sceneDesc.flags |= PxSceneFlag::eADAPTIVE_FORCE;

sceneDesc.flags |= PxSceneFlag::eENABLE_ACTIVETRANSFORMS;

sceneDesc.flags |= PxSceneFlag::eSUPPRESS_EAGER_SCENE_QUERY_REFIT;

//sceneDesc.flags |= PxSceneFlag::eDISABLE_CONTACT_CACHE;

//sceneDesc.broadPhaseType = PxBroadPhaseType::eGPU;

sceneDesc.gpuMaxNumPartitions = 8;

//sceneDesc.flags |= PxSceneFlag::eREQUIRE_RW_LOCK;

PxScene* scene = mPhysics->createScene(sceneDesc);

PxRigidDynamic* box;

for (int i = 0; i < 250; i++)

{

box = PxCreateDynamic(*mPhysics, PxTransform(PxVec3(0.0f, 0.0f, 0.0f)), PxBoxGeometry(PxVec3(1.0, 1.0 *i, 1.0)), *mMaterial, 0.5);

box->setMass(0.0);

//box->setAngularDamping(100);

scene->addActor(*box);

box->addForce(PxVec3(10.0f, 0.0f, 0.0f));

}

auto tim = time(nullptr);

for (int i = 0; i < 100; i++)

{

scene->simulate(0.016f);

scene->fetchResults(true);

//while (!scene->fetchResults(false))

{

}

}

cout << time(nullptr) - tim << " " << box->getLinearVelocity().magnitude() << endl;

//scene->addActor(*box);

system("pause");

/*gSampleCommandLine = new SampleCommandLine(GetCommandLineA());

mainInitialize();

mainLoop();

mainTerminate();*/

return 0;

}

输出分别是

9cd0c470ebb376e65ceed429913f6f20.png     

95dedcb9f9a949d9303bbbec9a2070d9.png

调整为10个刚体, 模拟100W次 输出结果为

67bacc33dea6328388281227ff4b269b.png

TODO

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值