[3D] Low Poly 3D Object

Hello Developers,

I was recently testing some 3D features and came across " Physics 3D Collision Callback " test.

As being told by one of my Unity colleague, that’s a lot of polygons and it will slow down rendering and eventually your gameplay. Also, he advised me to use a “LOW-POLY MESH COLLIDER” as that would improve the performance.

Does anybody knows how to achieve that…!!
Since there’s a few threads and very few replies to them, may I seek your help @super626 …!!
Also, if you could direct me with some documentation that would also be great, other than programmer’s guide and source code… ha ha… :smile:

Thanks in advance.

Regards,
Pabitra

2 Likes

Hi @pabitrapadhy,

Your question is good. Physics objects with lots of polygons are low efficiency. We are creating the editor to help you making physics objects.

You can do the following before physics editor is ready,

  1. Just use the 3D model to create physics object if you model has a few polygons or there are a few physics objects in you scene.

  2. Combine the physics object with a few basic geometries. Take the plane for example, a box for the plane body, and four boxes for the plane swings. However, you’d better create a simple editor to combine the basic geometries.

  3. Have you artist make a simpler model, which is used to create physics object.

Hello @super626

UPDATE :

I am able to get 60.0 fps now, while testing in iOS devices.

It’s great to hear that a physics editor is coming up. Looking forward to it.
In the meantime, I considered your suggestions and tried to check with a simple sample with a basic 3D model.
Unfortunately, once the scene is created, from the start only, the frame rate decreases to 30 FPS.

Here’s a screenshot -

Attaching my code and the 3D model (.fbx file). Please review it at your ease.
May be I am doing something wrong, guide me wherever required.

CODE : ( taken from cpp-tests and modified a little )

#include "HelloWorldScene.h"

#include "physics3d/CCPhysics3D.h"
#include "3d/CCBundle3D.h"

USING_NS_CC;

static cocos2d::Scene* physicsScene = nullptr;

Scene* HelloWorld::createScene()
{
    // 'scene' is an autorelease object
    auto scene = Scene::createWithPhysics();
    
    scene->getPhysics3DWorld()->setGravity(Vec3(0, -10, 0));
    scene->getPhysics3DWorld()->setDebugDrawEnable(true);
    scene->getPhysics3DWorld()->stepSimulate(1/100);
    scene->getPhysicsWorld()->setAutoStep(false);
    
    physicsScene = scene;
    
    // 'layer' is an autorelease object
    auto layer = HelloWorld::create();
    layer->setPhysics3DWorld(scene->getPhysics3DWorld());

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Layer::init() )
    {
        return false;
    }
    
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();
    
    
    //CAMERA
    _camera = Camera::createPerspective(60, (GLfloat)visibleSize.width/visibleSize.height, 1, 1000);
    _camera->setCameraFlag(CameraFlag::USER1);
    _camera->setPosition3D(Vec3(0, 0, 100));
    _camera->lookAt(Vec3(0, 0, 0), Vec3(0, 1, 0));
    _camera->retain();
    this->addChild(_camera);
    
    auto listener = EventListenerTouchAllAtOnce::create();
    listener->onTouchesBegan = CC_CALLBACK_2(HelloWorld::onTouchesBegan, this);
    listener->onTouchesMoved = CC_CALLBACK_2(HelloWorld::onTouchesMoved, this);
    listener->onTouchesEnded = CC_CALLBACK_2(HelloWorld::onTouchesEnded, this);
    
    _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);


    
    Physics3DRigidBodyDes rbDes;
    
    float scale = 60.0f;
    std::vector<Vec3> trianglesList = Bundle3D::getTrianglesList("cube.c3b");
    for (auto& it : trianglesList) {
        it *= scale;
    }
    
    rbDes.mass = 0.0f;
    rbDes.shape = Physics3DShape::createMesh(&trianglesList[0], (int)trianglesList.size() / 3);
    
    auto rigidBody = Physics3DRigidBody::create(&rbDes);
    rigidBody->setRestitution(1.0f);
    
    auto component = Physics3DComponent::create(rigidBody);
    
    auto sprite = Sprite3D::create("cube.c3b", "cube_diff.png");
    sprite->addComponent(component);
    sprite->setRotation3D(Vec3(0.0f, 0.0f, 0.0f));
    sprite->setScale(scale);
    sprite->setCameraMask((unsigned short)CameraFlag::USER1);
    sprite->setPosition3D(Vec3(0.0f,0.0f,0.0f));
    this->addChild(sprite);

    
    //DEBUG CAMERA
    physicsScene->setPhysics3DDebugCamera(_camera);
    
    
    return true;
}

void HelloWorld::onTouchesBegan(const std::vector<Touch*>& touches, cocos2d::Event  *event)
{
    event->stopPropagation();
}

void HelloWorld::onTouchesMoved(const std::vector<Touch*>& touches, cocos2d::Event  *event)
{
    if (touches.size() && _camera)
    {
        auto touch = touches[0];
        auto delta = touch->getDelta();
        
        _angle -= CC_DEGREES_TO_RADIANS(delta.x);
        _camera->setPosition3D(Vec3(100.0f * sinf(_angle), 0.0f, 100.0f * cosf(_angle)));
        _camera->lookAt(Vec3(0.0f, 0.0f, 0.0f), Vec3(0.0f, 1.0f, 0.0f));
        
        event->stopPropagation();
    }
}

void HelloWorld::onTouchesEnded(const std::vector<Touch*>& touches, cocos2d::Event  *event)
{
//    if (!_needShootBox) return;
    if (!touches.empty())
    {
        auto location = touches[0]->getLocationInView();
        
        Vec3 nearP(location.x, location.y, -1.0f), farP(location.x, location.y, 1.0f);
        nearP = _camera->unproject(nearP);
        farP = _camera->unproject(farP);
        Vec3 dir(farP - nearP);
        shootBox(_camera->getPosition3D() + dir * 10.0f);
        event->stopPropagation();
    }
}


void HelloWorld::shootBox( const cocos2d::Vec3 &des )
{
    Physics3DRigidBodyDes rbDes;
    Vec3 linearVel = des - _camera->getPosition3D();
    linearVel.normalize();
    linearVel *= 100.0f;
    rbDes.originalTransform.translate(_camera->getPosition3D());
    rbDes.mass = 10.0f;
    
    
    rbDes.shape = Physics3DShape::createSphere(2.0f);//createBox(Vec3(0.5f, 0.5f, 0.5f));
    auto sprite = PhysicsSprite3D::create("Sprite3DTest/ball.c3b", &rbDes);
    sprite->setTexture("Sprite3DTest/teapot.png");
    
    auto rigidBody = static_cast<Physics3DRigidBody*>(sprite->getPhysicsObj());
    rigidBody->setLinearFactor(Vec3::ONE);
    rigidBody->setLinearVelocity(linearVel);
    rigidBody->setAngularVelocity(Vec3::ZERO);
    rigidBody->setCcdMotionThreshold(0.5f);
    rigidBody->setCcdSweptSphereRadius(0.5f);
    rigidBody->setRestitution(0.2);
    
    this->addChild(sprite);
    sprite->setPosition3D(_camera->getPosition3D());
    sprite->setScale(0.4f);
    sprite->syncNodeToPhysics();
    
    //optimize, only sync node to physics
    sprite->setSyncFlag(Physics3DComponent::PhysicsSyncFlag::PHYSICS_TO_NODE); //sync node to physics
    
    sprite->setCameraMask((unsigned short)CameraFlag::USER1);
}

3D MODEL : 3D_Model.zip (8.9 KB)

Any suggestions are welcome. :smile:
Thanks in advance.

Regards,
Pabitra

Hi @pabitrapadhy,

I do not find there is any problems. Can you give me some detail of your devices? In fact, physics do cost some cpu time.