Cocos2D-X : Parsing list of objects from a TMX file, migrating code from version 2.X to version 3.X - c++

I am new to Cocos2D-X and have been trying to learn it for the past couple months now. I am trying to create a sample game from the book Cocos2d-x Game Development Blueprints and in this particular chapter it's explaining how to create a game using tiled map.
I Need help parsing a list of objects from a TMX file, I am trying to update the code from version 2.X to version 3.X, because I get compile errors. I need to change the deprecated CCArray and CCDictionary into the new cocos::Vector and Map in the following code
void GameWorld::CreateTiledMap()
{
// generate level filename
char buf[128] = {0};
sprintf(buf, "level_%02d.tmx", GameGlobals::level_number_);
// create & add the tiled map
tiled_map_ = CCTMXTiledMap::create(buf);
addChild(tiled_map_);
// get the size of the tiled map
columns_ = (int)tiled_map_->getMapSize().width;
rows_ = (int)tiled_map_->getMapSize().height;
// save a reference to the layer containing all the bricks
bricks_layer_ = tiled_map_->layerNamed("Bricks");
// parse the list of objects
CCTMXObjectGroup* object_group = tiled_map_->objectGroupNamed("Objects");
CCArray* objects = object_group->getObjects();
int num_objects = objects->count();
for(int i = 0; i < num_objects; ++i)
{
CCDictionary* object = (CCDictionary*)(objects->objectAtIndex(i));
// create the Hero at this spawning point
if(strcmp(object->valueForKey("name")->getCString(), "HeroSpawnPoint") == 0)
{
CreateHero(ccp(object->valueForKey("x")->floatValue(), object->valueForKey("y")->floatValue()));
}
// create an Enemy at this spawning point
else if(strcmp(object->valueForKey("name")->getCString(), "EnemySpawnPoint") == 0)
{
CCPoint position = ccp(object->valueForKey("x")->floatValue(), object->valueForKey("y")->floatValue());
CCPoint speed = ccp(object->valueForKey("speed_x")->floatValue(), object->valueForKey("speed_y")->floatValue());
CreateEnemy(position, speed);
}
// create a Platform at this spawning point
else if(strcmp(object->valueForKey("name")->getCString(), "PlatformSpawnPoint") == 0)
{
CCPoint position = ccp(object->valueForKey("x")->floatValue(), object->valueForKey("y")->floatValue());
CCPoint speed = ccp(object->valueForKey("speed_x")->floatValue(), object->valueForKey("speed_y")->floatValue());
CreatePlatform(position, speed);
}
// save the point where the level should complete
else if(strcmp(object->valueForKey("name")->getCString(), "LevelCompletePoint") == 0)
{
level_complete_height_ = object->valueForKey("y")->floatValue();
}
}
}
I have tried converting it myself, but have been unsuccessful.
I am having trouble converting the CCArray to cocos::Vector,
but mainly changing the CCDictionary to cocos::Map. Can someone Please help me?

Cocos2d-x has many tests, which is very helpful. From \tests\cpp-tests\Classes\TileMapTest\TileMapTest.cpp:
auto map = TMXTiledMap::create("TileMaps/test-object-layer.tmx");
addChild(map, -1, kTagTileMap);
CCLOG("----> Iterating over all the group objets");
auto group = map->getObjectGroup("Objects");
auto& objects = group->getObjects();
for (auto& obj : objects)
{
ValueMap& dict = obj.asValueMap();
float x = dict["x"].asFloat();
string name = dict["name"].asString();
}

Related

SFML How to draw heap of multiple textures at specific time

Hello I'm making a game using SFML, but I ran into some problems.
I want to complete this function:
if a human character collide with items, one garbage draw on screen. (5 textures)
So multiple textures of garbages stack up from the bottom of the window.
I tried to use vector and Sprite array, but my codes can't add garbages. It just draw one garbage, and then change another textures.
What should I do to keep garbages drawn until window closes?
I should add many Sprites to solve this problem, but I have no ideas... I've done everything I can.
My code is here:
// out of main loop
Texture GarbagesTexture[5];
GarbagesTexture[0] = garbageTex1;
GarbagesTexture[1] = garbageTex2;
GarbagesTexture[2] = garbageTex3;
GarbagesTexture[3] = garbageTex4;
GarbagesTexture[4] = garbageTex5;
int SelectedGarbage = 0;
vector<Sprite> Garbages;
Position GarbagesPosition;
GarbagesPosition.x = 890.f;
GarbagesPosition.y = 590.f;
// main loop
//collision
for (size_t i = 0; i < items.size(); i++)
{
if (humanArr[index].getGlobalBounds().intersects(item[i].getGlobalBounds()))
{
...
...
CollisionTime++;
SelectedGarbage++;
if (SelectedGarbage > 5) SelectedGarbage = 0;
GarbagesPosition.x = GarbagesPosition.x - 10.f;
GarbagesPosition.y = GarbagesPosition.y - 5.f;
Sprite GarbageInputSprite;
Garbages.push_back(GarbageInputSprite);
Garbages[i].setTexture(GarbagesTexture[SelectedGarbage];
Garbages[i].setPosition(GarbagesPosition.x, GarbagesPosition.y);
}
}
//draw
window.clear();
...
...
for (int i = 0; i < CollisionTime; i++)
window.draw(Garbages[i]);
window.display();
I am a poor beginner in SFML, but I'll try to do my best.
I would really appreciate it if you could help me solve this problem.

Slow application if the number of Markers increases

On an OpenStreetMap map with osmDroid and osmBonusPack I display markers and by clicking on it a bubble opens, everything works as I want up to a certain number of markers.
The more markers I put on the map, the less responsive the application is.
For example with 1000 markers, it takes 6 seconds for the Toolbar menu to appear and as much for moving to another activity such as a simple text display.
My code.
private void creationMarker(GeoPoint arg,
String titre,
String proximite,
String description,
String identifiant) {
double doubleProximite;
Marker startMarker = new Marker(map);
startMarker.setPosition(arg);
startMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
InfoWindow infoWindow = new MyInfoWindow(R.layout.bonuspack_bubble_black, map);
((MyInfoWindow) infoWindow).setTitre(titre);
((MyInfoWindow) infoWindow).setDescription(description);
((MyInfoWindow) infoWindow).setSubDescription(identifiant);
startMarker.setTitle(((MyInfoWindow) infoWindow).getTitre());
startMarker.setTitle(((MyInfoWindow) infoWindow).getDescription());
startMarker.setTitle(((MyInfoWindow) infoWindow).getSubDescription());
startMarker.setIcon(getResources().getDrawable(R.drawable.croix_verte, null).mutate());
startMarker.setInfoWindow(infoWindow);
doubleProximite = Double.parseDouble(proximite);
Polygon circle = new Polygon();
circle.setPoints(Polygon.pointsAsCircle(arg, doubleProximite));
int myColorZone, myColorCloture;
myColorZone = this.getResources().getColor(R.color.SurfaceZoneActive, getTheme());
circle.setFillColor(myColorZone); // couleur avec arrière plan transparent
myColorCloture = this.getResources().getColor(R.color.ClotureActive, getTheme());
circle.setStrokeColor(myColorCloture);// couleur de la circonférence
circle.setStrokeWidth(3); // épaisseur du trait
map.getOverlays().add(circle);
map.getOverlays().add(startMarker);
}
I use a loop with an SQL database for the marker data.
I guess the more markers there are, the more events the app has to handle.
What solutions could solve my problem.
Thank you in advance for your answers
Markers are quite heavyweight or at least they have been some time ago when I had similar performance issues as you have. There might be a potential to optimize them, but that would mean modifying the Osmdroid library and creating a pull request with such changes.
Try to do some profiling to make sure the problem is not in your code but in the library (https://developer.android.com/studio/profile/cpu-profiler.html).
Pay attention to how you read the data from the databse - don't do it on main thread and measure how long it takes to make sure it's not the main issue.
Try SimpleFastPointOverlay from Osmdrid - it is supposed to be optimized for higher numbers of Markers (they have to have the same icon, though). Even if its not flexible enough for your needs, try it out to verify Markers are the real problem. After that you can look at the source code and use it as a learning material to implement your own custom Overlay.
A month has passed, I have a solution, I studied the project https://github.com/MKergall/osmbonuspack in the folder
https://github.com/MKergall/osmbonuspack/tree/master/OSMBonusPack/src/main/java/org/osmdroid/bonuspack/clustering
there are three files that interested me to manage clustering.
MarkerClusterer.java
RadiusMarkerClusterer.java
StaticCluster.java
Thanks to M.Kergall and Roman Sidorov who are the creators of these java sources.
I simply copied these files into a test project. I was inspired by the methods that manage Markers in order to put circular Polygons, clustering side it works well, but depending on the zoom level, when the circular polygons are drawn there is no longer any interest in clustering. I countered this problem by managing the drawings of the polygons from the screen, I draw that what there is the screen, ditto for the Markers. Now with 20,000 Markers and Polygons it's just starting to hinder the responsiveness of the application, when before it was around 200. Here are some code snippets below.
Here are some code snippets below.
Main activity code
private void getlireDataBaseMarkers() {
bar.setVisibility(View.VISIBLE);
bar.getLayoutParams().height = 6;
bar.requestLayout();
Thread t = new Thread(){
public void run() {
Bundle messageBundle=new Bundle();
nbrMarker = 0;
dbMarkers = new DBHelper(MainActivity.this);
if (dbMarkers.numberOfRows() == 0) {
return;
}
SQLiteDatabase db = dbMarkers.getReadableDatabase();
Cursor res = db.rawQuery(SqlOrderVisibilite, null);
res.moveToFirst();
int qtyMarkers = dbMarkers.numberOfRows();
bar.setMax(qtyMarkers);
bar.setProgress(0);
MyRadiusMarkerClusterer radiusMarkers = new MyRadiusMarkerClusterer(MainActivity.this);
Double zoom = 15.0;
radiusMarkers.setMaxPolygonZoomLevel(zoom);
GeoPoint lePoint = new GeoPoint(0.0, 0.0, 0.0);
while (!res.isAfterLast() &&
!isPausing.get() &&
isRunning.get()) {
lePoint.setLatitude(res.getDouble(res.getColumnIndex(MARKERS_COLUMN_LATITUDE)));
lePoint.setLongitude(res.getDouble(res.getColumnIndex(MARKERS_COLUMN_LONGITUDE)));
Marker startMarker = new Marker(map);
startMarker.setPosition(lePoint);
startMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
startMarker.setIcon(getResources().getDrawable(R.drawable.person, null).mutate());
Polygon circle = new Polygon(map);
int myColorZone, myColorCloture;
circle.setPoints(Polygon.pointsAsCircle(lePoint,getRandomDoubleBetweenRange(20,200)));
myColorZone = MainActivity.this.getResources().getColor(R.color.colorAccent, getTheme());
circle.setFillColor(myColorZone);
myColorCloture = MainActivity.this.getResources().getColor(colorPrimary, getTheme());
circle.getOutlinePaint().setColor(myColorCloture);
circle.getOutlinePaint().setStrokeWidth(4);
radiusMarkers.add(startMarker);
radiusMarkers.add(circle);
nbrMarker++;
myMessage = handler.obtainMessage();
messageBundle.putInt(WRITE_QTY_MARKERS,2); // incrémenter le progress bar
myMessage.setData(messageBundle);
handler.sendMessage(myMessage);
res.moveToNext();
}
map.getOverlays().add(radiusMarkers);
res.close();
dbMarkers.close();
myMessage = handler.obtainMessage();
messageBundle.putInt(WRITE_QTY_MARKERS,1); // afficher le nombre de markers
myMessage.setData(messageBundle);
handler.sendMessage(myMessage);
}
};
isRunning.set(true);
isPausing.set(false);
t.start();
}
part of MyMarkerClusterers code
#Override
public void draw (Canvas canvas, MapView mapView,boolean shadow){
//if zoom has changed and mapView is now stable, rebuild clusters:
// si le zoom a changé et que mapView est maintenant stable, reconstruisez les groupes
Double zoomLevel = mapView.getZoomLevelDouble();
//if (zoomLevel != mLastZoomLevel && !mapView.isAnimating()) {
if (!mapView.isAnimating()) {
mClusters = clusterer(mapView);
pClusters = pclusterer(mapView);
renderer(mClusters, pClusters, canvas, mapView);
setmLastZoomLevel(zoomLevel);
}
for (MyStaticCluster cluster : mClusters) {
cluster.getMarker().draw(canvas, mapView, shadow);
}
for (MyStaticCluster cluster : pClusters) {
if (getmLastZoomLevel() > mMaxPolygonZoomLevel) {
cluster.getPolygon().draw(canvas, mapView, shadow);
}
}
}
part of MyRadiusMarkerClusterer code
#Override
public ArrayList<MyStaticCluster> clusterer(MapView mapView) {
ArrayList<MyStaticCluster> clusters = new ArrayList<>();
convertRadiusToMeters(mapView);
mClonedMarkers = new ArrayList<>(); //shallow copy
ArrayList<Marker> mFiltreMarkers = new ArrayList<>(mItems);
Iterator<Marker> it = mFiltreMarkers.iterator();
while (it.hasNext()){
Marker valeur = it.next();
GeoPoint point = valeur.getPosition();
// limiter le nombre de Marker suivant l'écran
if( mapView.getProjection().getNorthEast().getLatitude() >= point.getLatitude() &&
mapView.getProjection().getNorthEast().getLongitude() >= point.getLongitude() &&
mapView.getProjection().getSouthWest().getLatitude() <= point.getLatitude() &&
mapView.getProjection().getSouthWest().getLongitude() <= point.getLongitude()) {
mClonedMarkers.add(valeur);
}
it.remove();
}
while (!mClonedMarkers.isEmpty()) {
Marker m = mClonedMarkers.get(0);
MyStaticCluster cluster = createCluster(m,null, mapView);
clusters.add(cluster);
}
return clusters;
}
#Override public ArrayList<MyStaticCluster> pclusterer(MapView mapView) {
ArrayList<MyStaticCluster> clusters = new ArrayList<>();
convertRadiusToMeters(mapView);
pClonedPolygon = new ArrayList<> (); //shallow copy
ArrayList<Polygon> pFiltrePolygon = new ArrayList<>(pItems);
Iterator<Polygon> it = pFiltrePolygon.iterator();
while (it.hasNext()){
Polygon valeur = it.next();
GeoPoint point = valeur.getInfoWindowLocation();
// limiter le nombre de Polygon suivant l'écran
if( mapView.getProjection().getNorthEast().getLatitude() >= point.getLatitude() &&
mapView.getProjection().getNorthEast().getLongitude() >= point.getLongitude() &&
mapView.getProjection().getSouthWest().getLatitude() <= point.getLatitude() &&
mapView.getProjection().getSouthWest().getLongitude() <= point.getLongitude()) {
pClonedPolygon.add(valeur);
}
it.remove();
}
while (!pClonedPolygon.isEmpty()) {
Polygon p = pClonedPolygon.get(0);
MyStaticCluster cluster = createCluster(null,p, mapView);
clusters.add(cluster);
}
return clusters;
}

Stockfish Engine breaks when loaded from a view controller instead of the app delegate iOS

I trying to implement the Stockfish UCI engine into a chess game app. Originally in the Stockfish iOS game the view controller that holds the board and the pieces is loaded from the app delegate. What I am trying to do is have a few more screens before navigating to the game. The problem I have is that the as soon as I load the board screen the game breaks in bitboard.cpp file with the message EXC_BAD_ACCESS(code=1, address=0x1fa80000) and a few times I have managed to load the pieces on the board and move one of them but then it brakes in the same place shown below on this line: occupancy[size] = b;
void init_magics(Bitboard table[], Bitboard* attacks[], Bitboard magics[],
Bitboard masks[], unsigned shifts[], Square deltas[], Fn index) {
int MagicBoosters[][8] = { { 969, 1976, 2850, 542, 2069, 2852, 1708, 164 },
{ 3101, 552, 3555, 926, 834, 26, 2131, 1117 } };
RKISS rk;
Bitboard occupancy[4096], reference[4096], edges, b;
int i, size, booster;
// attacks[s] is a pointer to the beginning of the attacks table for square 's'
attacks[SQ_A1] = table;
for (Square s = SQ_A1; s <= SQ_H8; ++s)
{
// Board edges are not considered in the relevant occupancies
edges = ((Rank1BB | Rank8BB) & ~rank_bb(s)) | ((FileABB | FileHBB) & ~file_bb(s));
// Given a square 's', the mask is the bitboard of sliding attacks from
// 's' computed on an empty board. The index must be big enough to contain
// all the attacks for each possible subset of the mask and so is 2 power
// the number of 1s of the mask. Hence we deduce the size of the shift to
// apply to the 64 or 32 bits word to get the index.
masks[s] = sliding_attack(deltas, s, 0) & ~edges;
shifts[s] = (Is64Bit ? 64 : 32) - popcount<Max15>(masks[s]);
// Use Carry-Rippler trick to enumerate all subsets of masks[s] and
// store the corresponding sliding attack bitboard in reference[].
b = size = 0;
do {
occupancy[size] = b;
reference[size] = sliding_attack(deltas, s, b);
if (HasPext)
attacks[s][_pext_u64(b, masks[s])] = reference[size];
size++;
b = (b - masks[s]) & masks[s];
} while (b);
// Set the offset for the table of the next square. We have individual
// table sizes for each square with "Fancy Magic Bitboards".
if (s < SQ_H8)
attacks[s + 1] = attacks[s] + size;
if (HasPext)
continue;
booster = MagicBoosters[Is64Bit][rank_of(s)];
// Find a magic for square 's' picking up an (almost) random number
// until we find the one that passes the verification test.
do {
do magics[s] = rk.magic_rand<Bitboard>(booster);
while (popcount<Max15>((magics[s] * masks[s]) >> 56) < 6);
std::memset(attacks[s], 0, size * sizeof(Bitboard));
// A good magic must map every possible occupancy to an index that
// looks up the correct sliding attack in the attacks[s] database.
// Note that we build up the database for square 's' as a side
// effect of verifying the magic.
for (i = 0; i < size; ++i)
{
Bitboard& attack = attacks[s][index(s, occupancy[i])];
if (attack && attack != reference[i])
break;
assert(reference[i]);
attack = reference[i];
}
} while (i < size);
}
I have not much experience and knowledge in C++ and I am struggling to figure out what is causing the issue.
I have managed to sort it out now! I figured that the game was still initialising while I was loading its view and this caused the whole issue, because the initialiser was running in the background! To sort it out I have made a loading screen and called the initialisers for the game there! And once it is all set up in the background I load the screen with the game!!! Hope my post helps someone in the future!

Slowdown when loading the same SpriteFrame used in an animation in Cocos2dx

I am currently experiencing some heavy slowdowns with my game. I have narrowed it down to something related with texture animations.
In my game there are characters that walk in 1 of 4 possible directions, they will walk up to a point, then change direction and continue walking (sort of like a tower defense game).
First i am loading the sprite frame cache like this
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("characters.plist");
This code is only run once during the life time of my application.
When the characters get loaded to the screen their animation is being set using the following code:
int direction = 0;
int number = 0;
if (this->to_x < 0) // Left
{
direction = 1;
number = 1;
}
else if(this->to_x > 0) // Right
{
direction = 2;
number = 1;
}
if (this->to_y < 0) // Down
{
direction = 0;
number = 0;
}
else if(this->to_y > 0) // Up
{
direction = 3;
number = 2;
}
int s = 0; //skin
// Set the animation
Animation *animation = Animation::create();
for (int i = 0; i < INT16_MAX; i++)
{
string frame_sprite_name = StringUtils::format("%s_%d_%d_%d.png",parameters[name].image_name.c_str(),s,number,i);
auto frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(frame_sprite_name);
if (frame) {
animation->addSpriteFrame(frame);
} else {
break;
}
}
// Invert the sprite when they go right
if (direction == 2) {
setFlippedX(true);
}else{
setFlippedX(false);
}
// Set the pace of the animation based on the type
if (name=="runner") {
animation->setDelayPerUnit(0.15f);
} else{
animation->setDelayPerUnit(0.3f);
}
Animate *animate = Animate::create(animation);
this->stopAllActions();
this->runAction(RepeatForever::create(animate));
What this code does is:
Check the direction
Get the sprite frame from the cache based on the direction
Run the action with repeat forever.
However this code is ran every time they change direction to set the new animation of the active characters. Also, at one time I can have around 40-50 of these characters going around.
I've noticed that after a few minutes in the game the slowdown starts to happen as soon as a new "character" is created, (since they are created in rapid succession in waves). And the slowdown also happens when the characters change in direction. So this makes me believe I am using the textures wrong.
If anyone knows how to fix this please let me know.
PD: I was thinking about the possibility of pre-loading all the animations and then just having each of the sprites that represent the characters run the corresponding animation.
You should definitely cache the animation in the AnimationCache with addAnimation and getAnimation methods.

Bullet Physics - Creating ShapeHull from Mesh

I am attempting to load mesh data that I use to draw with OpenGL into the Bullet Engine.
The problem is I don't believe that the mesh data is actually being read from the pointers. Thus the physical world is not matching up and the "Character Controller" is falling through the floor.
The rendered world is fine, so I know the OpenGL data is fine.
Here is the function of my controller class that I am using to transfer the data into OpenGL.
Is there something I am missing here?
Thank you - Here's the code I am using:
void PhysicsController::AddStaticBasicMesh(PhysicsObject* NewObject, bool ReducePolygonCount = true)
{
btTriangleMesh* OriginalTriangleMesh = new btTriangleMesh();
btIndexedMesh* NewMesh = new btIndexedMesh();
NewMesh->m_triangleIndexBase = (unsigned char *)NewObject->Indices;
NewMesh->m_triangleIndexStride = 3 * sizeof(unsigned int);
NewMesh->m_vertexBase = (unsigned char *)NewObject->Vertices;
NewMesh->m_vertexStride = 3 * sizeof(float);
NewMesh->m_numVertices = NewObject->NumberOfVertices;
NewMesh->m_numTriangles = NewObject->NumberOfTriangles;
OriginalTriangleMesh->addIndexedMesh((*NewMesh));
btConvexShape* NewStaticMesh = new btConvexTriangleMeshShape(OriginalTriangleMesh);
btConvexHullShape* ReducedPolygonStaticMesh;
if (ReducePolygonCount == true) {
btShapeHull* HullOfOriginalShape = new btShapeHull(NewStaticMesh);
btScalar CurrentMargin = NewStaticMesh->getMargin();
HullOfOriginalShape->buildHull(CurrentMargin);
ReducedPolygonStaticMesh = new btConvexHullShape();
for (int i = 0; i < HullOfOriginalShape->numVertices(); i++) {
ReducedPolygonStaticMesh->addPoint(HullOfOriginalShape->getVertexPointer()[i], false);
}
ReducedPolygonStaticMesh->recalcLocalAabb();
/*
Find out what this line does.
ReducedPolygonStaticMesh->initializePolyhedralFeatures();
*/
StaticShapes.push_back(ReducedPolygonStaticMesh);
btDefaultMotionState* StaticMotionState = new btDefaultMotionState((*NewObject->PositionAndOrientation));
btRigidBody::btRigidBodyConstructionInfo StaticMeshRigidBodyInfo(0, StaticMotionState, ReducedPolygonStaticMesh, btVector3(0.0f, 0.0f, 0.0f));
btRigidBody* StaticRigidMesh = new btRigidBody(StaticMeshRigidBodyInfo);
NewObject->Body = StaticRigidMesh;
StaticRigidMesh->setCollisionFlags(StaticRigidMesh->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
MainPhysicsWorld->addRigidBody(StaticRigidMesh, btBroadphaseProxy::StaticFilter, btBroadphaseProxy::CharacterFilter | btBroadphaseProxy::DefaultFilter);
AllRigidBodies.push_back(NewObject);
StaticRigidMesh->setUserPointer(AllRigidBodies[AllRigidBodies.size() - 1]);
delete HullOfOriginalShape;
delete NewStaticMesh;
} else {
StaticShapes.push_back(NewStaticMesh);;
btDefaultMotionState* StaticMotionState = new btDefaultMotionState((*NewObject->PositionAndOrientation));
btRigidBody::btRigidBodyConstructionInfo StaticMeshRigidBodyInfo(0, StaticMotionState, NewStaticMesh, btVector3(0.0f, 0.0f, 0.0f));
btRigidBody* StaticRigidMesh = new btRigidBody(StaticMeshRigidBodyInfo);
NewObject->Body = StaticRigidMesh;
StaticRigidMesh->setCollisionFlags(StaticRigidMesh->getCollisionFlags() | btCollisionObject::CF_STATIC_OBJECT);
MainPhysicsWorld->addRigidBody(StaticRigidMesh, btBroadphaseProxy::StaticFilter, btBroadphaseProxy::CharacterFilter | btBroadphaseProxy::DefaultFilter);
AllRigidBodies.push_back(NewObject);
StaticRigidMesh->setUserPointer(AllRigidBodies[AllRigidBodies.size() - 1]);
}
}
Maybe, not the answer you're looking for, but probably you could use btConvexHullShape, as advised in Bullet documentation?
http://bulletphysics.org/Bullet/BulletFull/classbtConvexTriangleMeshShape.html
Nevertheless, most users should use the much better performing
btConvexHullShape instead.
And add vertices one by one using addPoint, which is also mentioned in documentation:
http://bulletphysics.org/Bullet/BulletFull/classbtConvexHullShape.html
It is easier to not pass any points in the constructor, and just add
one point at a time, using addPoint
I know it is bad to answer "just use something else" instead of answering the original question.
Also this way you'll duplicate your vertices.
However, if you're only beginning to learn some new tech, you might want to make everything work first and then it might be easier to return step-by-step to your original design.
Another good idea would be to use debug drawer and actually see what your mesh looks like.
I've created one, some time ago for OpenGL ES 2.0, maybe it will be helpful:
https://github.com/kmuzykov/custom-opengl-es-game-engine/blob/master/Engine/Physics/KMPhysicsDebugDrawer.cpp