Merge pull request #2367 from erwincoumans/master
allow to update heightfield, see PyBullet: allow to update an existing heightfield shape Also, use flags = p.GEOM_CONCAVE_INTERNAL_EDGE to enable internal edge filtering for heightfield (disabled by default) See https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/heightfield.py
This commit is contained in:
@@ -47,7 +47,7 @@ struct GUIHelperInterface
|
|||||||
virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]) {}
|
virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]) {}
|
||||||
virtual void changeSpecularColor(int instanceUid, const double specularColor[3]) {}
|
virtual void changeSpecularColor(int instanceUid, const double specularColor[3]) {}
|
||||||
virtual void changeTexture(int textureUniqueId, const unsigned char* rgbTexels, int width, int height) {}
|
virtual void changeTexture(int textureUniqueId, const unsigned char* rgbTexels, int width, int height) {}
|
||||||
|
virtual void updateShape(int shapeIndex, float* vertices) {}
|
||||||
virtual int getShapeIndexFromInstance(int instanceUid) { return -1; }
|
virtual int getShapeIndexFromInstance(int instanceUid) { return -1; }
|
||||||
virtual void replaceTexture(int shapeIndex, int textureUid) {}
|
virtual void replaceTexture(int shapeIndex, int textureUid) {}
|
||||||
virtual void removeTexture(int textureUid) {}
|
virtual void removeTexture(int textureUid) {}
|
||||||
|
|||||||
@@ -1496,3 +1496,8 @@ void OpenGLGuiHelper::computeSoftBodyVertices(btCollisionShape* collisionShape,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLGuiHelper::updateShape(int shapeIndex, float* vertices)
|
||||||
|
{
|
||||||
|
m_data->m_glApp->m_renderer->updateShape(shapeIndex, vertices);
|
||||||
|
}
|
||||||
@@ -33,6 +33,7 @@ struct OpenGLGuiHelper : public GUIHelperInterface
|
|||||||
virtual void removeTexture(int textureUid);
|
virtual void removeTexture(int textureUid);
|
||||||
virtual int getShapeIndexFromInstance(int instanceUid);
|
virtual int getShapeIndexFromInstance(int instanceUid);
|
||||||
virtual void replaceTexture(int shapeIndex, int textureUid);
|
virtual void replaceTexture(int shapeIndex, int textureUid);
|
||||||
|
virtual void updateShape(int shapeIndex, float* vertices);
|
||||||
|
|
||||||
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape);
|
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape);
|
||||||
|
|
||||||
|
|||||||
@@ -1340,6 +1340,8 @@ B3_SHARED_API int b3CreateCollisionShapeAddHeightfield(b3SharedMemoryCommandHand
|
|||||||
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_heightfieldTextureScaling = textureScaling;
|
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_heightfieldTextureScaling = textureScaling;
|
||||||
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_numHeightfieldRows = -1;
|
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_numHeightfieldRows = -1;
|
||||||
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_numHeightfieldColumns = -1;
|
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_numHeightfieldColumns = -1;
|
||||||
|
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_replaceHeightfieldIndex = -1;
|
||||||
|
|
||||||
command->m_createUserShapeArgs.m_numUserShapes++;
|
command->m_createUserShapeArgs.m_numUserShapes++;
|
||||||
return shapeIndex;
|
return shapeIndex;
|
||||||
}
|
}
|
||||||
@@ -1347,7 +1349,7 @@ B3_SHARED_API int b3CreateCollisionShapeAddHeightfield(b3SharedMemoryCommandHand
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
B3_SHARED_API int b3CreateCollisionShapeAddHeightfield2(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, const double meshScale[/*3*/], double textureScaling, float* heightfieldData, int numHeightfieldRows, int numHeightfieldColumns)
|
B3_SHARED_API int b3CreateCollisionShapeAddHeightfield2(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, const double meshScale[/*3*/], double textureScaling, float* heightfieldData, int numHeightfieldRows, int numHeightfieldColumns, int replaceHeightfieldIndex)
|
||||||
{
|
{
|
||||||
PhysicsClient* cl = (PhysicsClient*)physClient;
|
PhysicsClient* cl = (PhysicsClient*)physClient;
|
||||||
b3Assert(cl);
|
b3Assert(cl);
|
||||||
@@ -1370,6 +1372,8 @@ B3_SHARED_API int b3CreateCollisionShapeAddHeightfield2(b3PhysicsClientHandle ph
|
|||||||
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_heightfieldTextureScaling = textureScaling;
|
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_heightfieldTextureScaling = textureScaling;
|
||||||
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_numHeightfieldRows = numHeightfieldRows;
|
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_numHeightfieldRows = numHeightfieldRows;
|
||||||
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_numHeightfieldColumns = numHeightfieldColumns;
|
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_numHeightfieldColumns = numHeightfieldColumns;
|
||||||
|
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_replaceHeightfieldIndex = replaceHeightfieldIndex;
|
||||||
|
|
||||||
cl->uploadBulletFileToSharedMemory((const char*)heightfieldData, numHeightfieldRows*numHeightfieldColumns* sizeof(float));
|
cl->uploadBulletFileToSharedMemory((const char*)heightfieldData, numHeightfieldRows*numHeightfieldColumns* sizeof(float));
|
||||||
command->m_createUserShapeArgs.m_numUserShapes++;
|
command->m_createUserShapeArgs.m_numUserShapes++;
|
||||||
return shapeIndex;
|
return shapeIndex;
|
||||||
|
|||||||
@@ -490,7 +490,7 @@ extern "C"
|
|||||||
B3_SHARED_API int b3CreateCollisionShapeAddCapsule(b3SharedMemoryCommandHandle commandHandle, double radius, double height);
|
B3_SHARED_API int b3CreateCollisionShapeAddCapsule(b3SharedMemoryCommandHandle commandHandle, double radius, double height);
|
||||||
B3_SHARED_API int b3CreateCollisionShapeAddCylinder(b3SharedMemoryCommandHandle commandHandle, double radius, double height);
|
B3_SHARED_API int b3CreateCollisionShapeAddCylinder(b3SharedMemoryCommandHandle commandHandle, double radius, double height);
|
||||||
B3_SHARED_API int b3CreateCollisionShapeAddHeightfield(b3SharedMemoryCommandHandle commandHandle, const char* fileName, const double meshScale[/*3*/], double textureScaling);
|
B3_SHARED_API int b3CreateCollisionShapeAddHeightfield(b3SharedMemoryCommandHandle commandHandle, const char* fileName, const double meshScale[/*3*/], double textureScaling);
|
||||||
B3_SHARED_API int b3CreateCollisionShapeAddHeightfield2(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, const double meshScale[/*3*/], double textureScaling, float* heightfieldData, int numHeightfieldRows, int numHeightfieldColumns);
|
B3_SHARED_API int b3CreateCollisionShapeAddHeightfield2(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, const double meshScale[/*3*/], double textureScaling, float* heightfieldData, int numHeightfieldRows, int numHeightfieldColumns, int replaceHeightfieldIndex);
|
||||||
|
|
||||||
B3_SHARED_API int b3CreateCollisionShapeAddPlane(b3SharedMemoryCommandHandle commandHandle, const double planeNormal[/*3*/], double planeConstant);
|
B3_SHARED_API int b3CreateCollisionShapeAddPlane(b3SharedMemoryCommandHandle commandHandle, const double planeNormal[/*3*/], double planeConstant);
|
||||||
B3_SHARED_API int b3CreateCollisionShapeAddMesh(b3SharedMemoryCommandHandle commandHandle, const char* fileName, const double meshScale[/*3*/]);
|
B3_SHARED_API int b3CreateCollisionShapeAddMesh(b3SharedMemoryCommandHandle commandHandle, const char* fileName, const double meshScale[/*3*/]);
|
||||||
|
|||||||
@@ -4428,6 +4428,37 @@ static unsigned char* MyGetRawHeightfieldData(CommonFileIOInterface& fileIO, PHY
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MyTriangleCollector4 : public btTriangleCallback
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
btAlignedObjectArray<GLInstanceVertex>* m_pVerticesOut;
|
||||||
|
btAlignedObjectArray<int>* m_pIndicesOut;
|
||||||
|
|
||||||
|
MyTriangleCollector4()
|
||||||
|
{
|
||||||
|
m_pVerticesOut = 0;
|
||||||
|
m_pIndicesOut = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void processTriangle(btVector3* tris, int partId, int triangleIndex)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < 3; k++)
|
||||||
|
{
|
||||||
|
GLInstanceVertex v;
|
||||||
|
v.xyzw[3] = 0;
|
||||||
|
v.uv[0] = v.uv[1] = 0.5f;
|
||||||
|
btVector3 normal = (tris[0] - tris[1]).cross(tris[0] - tris[2]);
|
||||||
|
normal.safeNormalize();
|
||||||
|
for (int l = 0; l < 3; l++)
|
||||||
|
{
|
||||||
|
v.xyzw[l] = tris[k][l];
|
||||||
|
v.normal[l] = normal[l];
|
||||||
|
}
|
||||||
|
m_pIndicesOut->push_back(m_pVerticesOut->size());
|
||||||
|
m_pVerticesOut->push_back(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
bool PhysicsServerCommandProcessor::processCreateCollisionShapeCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes)
|
bool PhysicsServerCommandProcessor::processCreateCollisionShapeCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes)
|
||||||
{
|
{
|
||||||
@@ -4571,43 +4602,109 @@ bool PhysicsServerCommandProcessor::processCreateCollisionShapeCommand(const str
|
|||||||
if (heightfieldData)
|
if (heightfieldData)
|
||||||
{
|
{
|
||||||
|
|
||||||
btScalar gridSpacing = 0.5;
|
//replace heightfield data or create new heightfield
|
||||||
btScalar gridHeightScale = 1. / 256.;
|
if (clientCmd.m_createUserShapeArgs.m_shapes[i].m_replaceHeightfieldIndex >=0)
|
||||||
|
{
|
||||||
|
int collisionShapeUid = clientCmd.m_createUserShapeArgs.m_shapes[i].m_replaceHeightfieldIndex;
|
||||||
|
|
||||||
bool flipQuadEdges = false;
|
InternalCollisionShapeHandle* handle = m_data->m_userCollisionShapeHandles.getHandle(collisionShapeUid);
|
||||||
int upAxis = 2;
|
if (handle && handle->m_collisionShape && handle->m_collisionShape->getShapeType() == TERRAIN_SHAPE_PROXYTYPE)
|
||||||
/*btHeightfieldTerrainShape* heightfieldShape = worldImporter->createHeightfieldShape( width, height,
|
{
|
||||||
heightfieldData,
|
btHeightfieldTerrainShape* terrainShape = (btHeightfieldTerrainShape*)handle->m_collisionShape;
|
||||||
|
btScalar* heightfieldDest = (btScalar*)terrainShape->getHeightfieldRawData();
|
||||||
|
//replace the data
|
||||||
|
|
||||||
|
btScalar* datafl = (btScalar*)heightfieldData;
|
||||||
|
|
||||||
|
for (int i = 0; i < width*height; i++)
|
||||||
|
{
|
||||||
|
heightfieldDest[i] = datafl[i];
|
||||||
|
}
|
||||||
|
//update graphics
|
||||||
|
|
||||||
|
btAlignedObjectArray<GLInstanceVertex> gfxVertices;
|
||||||
|
btAlignedObjectArray<int> indices;
|
||||||
|
int strideInBytes = 9 * sizeof(float);
|
||||||
|
|
||||||
|
|
||||||
|
MyTriangleCollector4 col;
|
||||||
|
col.m_pVerticesOut = &gfxVertices;
|
||||||
|
col.m_pIndicesOut = &indices;
|
||||||
|
btVector3 aabbMin, aabbMax;
|
||||||
|
for (int k = 0; k < 3; k++)
|
||||||
|
{
|
||||||
|
aabbMin[k] = -BT_LARGE_FLOAT;
|
||||||
|
aabbMax[k] = BT_LARGE_FLOAT;
|
||||||
|
}
|
||||||
|
terrainShape->processAllTriangles(&col, aabbMin, aabbMax);
|
||||||
|
if (gfxVertices.size() && indices.size())
|
||||||
|
{
|
||||||
|
m_data->m_guiHelper->updateShape(terrainShape->getUserIndex(), &gfxVertices[0].xyzw[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
terrainShape->clearAccelerator();
|
||||||
|
terrainShape->buildAccelerator();
|
||||||
|
|
||||||
|
|
||||||
|
btTriangleInfoMap* oldTriangleInfoMap = terrainShape->getTriangleInfoMap();
|
||||||
|
delete (oldTriangleInfoMap);
|
||||||
|
terrainShape->setTriangleInfoMap(0);
|
||||||
|
|
||||||
|
if (clientCmd.m_createUserShapeArgs.m_shapes[i].m_collisionFlags & GEOM_CONCAVE_INTERNAL_EDGE)
|
||||||
|
{
|
||||||
|
btTriangleInfoMap* triangleInfoMap = new btTriangleInfoMap();
|
||||||
|
btGenerateInternalEdgeInfo(terrainShape, triangleInfoMap);
|
||||||
|
}
|
||||||
|
serverStatusOut.m_createUserShapeResultArgs.m_userShapeUniqueId = collisionShapeUid;
|
||||||
|
delete worldImporter;
|
||||||
|
serverStatusOut.m_type = CMD_CREATE_COLLISION_SHAPE_COMPLETED;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete heightfieldData;
|
||||||
|
return hasStatus;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
btScalar gridSpacing = 0.5;
|
||||||
|
btScalar gridHeightScale = 1. / 256.;
|
||||||
|
|
||||||
|
bool flipQuadEdges = false;
|
||||||
|
int upAxis = 2;
|
||||||
|
/*btHeightfieldTerrainShape* heightfieldShape = worldImporter->createHeightfieldShape( width, height,
|
||||||
|
heightfieldData,
|
||||||
|
gridHeightScale,
|
||||||
|
minHeight, maxHeight,
|
||||||
|
upAxis, int(scalarType), flipQuadEdges);
|
||||||
|
*/
|
||||||
|
btHeightfieldTerrainShape* heightfieldShape = new btHeightfieldTerrainShape(width, height,
|
||||||
|
heightfieldData,
|
||||||
gridHeightScale,
|
gridHeightScale,
|
||||||
minHeight, maxHeight,
|
minHeight, maxHeight,
|
||||||
upAxis, int(scalarType), flipQuadEdges);
|
upAxis, scalarType, flipQuadEdges);
|
||||||
*/
|
m_data->m_collisionShapes.push_back(heightfieldShape);
|
||||||
btHeightfieldTerrainShape* heightfieldShape = new btHeightfieldTerrainShape( width, height,
|
|
||||||
heightfieldData,
|
|
||||||
gridHeightScale,
|
|
||||||
minHeight, maxHeight,
|
|
||||||
upAxis, scalarType, flipQuadEdges);
|
|
||||||
m_data->m_collisionShapes.push_back(heightfieldShape);
|
|
||||||
|
|
||||||
heightfieldShape->setUserValue3(clientCmd.m_createUserShapeArgs.m_shapes[i].m_heightfieldTextureScaling);
|
heightfieldShape->setUserValue3(clientCmd.m_createUserShapeArgs.m_shapes[i].m_heightfieldTextureScaling);
|
||||||
shape = heightfieldShape;
|
shape = heightfieldShape;
|
||||||
if (upAxis == 2)
|
if (upAxis == 2)
|
||||||
heightfieldShape->setFlipTriangleWinding(true);
|
heightfieldShape->setFlipTriangleWinding(true);
|
||||||
//buildAccelerator is optional, it may not support all features.
|
|
||||||
heightfieldShape->buildAccelerator();
|
|
||||||
|
|
||||||
// scale the shape
|
// scale the shape
|
||||||
btVector3 localScaling(clientCmd.m_createUserShapeArgs.m_shapes[i].m_meshScale[0],
|
btVector3 localScaling(clientCmd.m_createUserShapeArgs.m_shapes[i].m_meshScale[0],
|
||||||
clientCmd.m_createUserShapeArgs.m_shapes[i].m_meshScale[1],
|
clientCmd.m_createUserShapeArgs.m_shapes[i].m_meshScale[1],
|
||||||
clientCmd.m_createUserShapeArgs.m_shapes[i].m_meshScale[2]);
|
clientCmd.m_createUserShapeArgs.m_shapes[i].m_meshScale[2]);
|
||||||
|
|
||||||
heightfieldShape->setLocalScaling(localScaling);
|
heightfieldShape->setLocalScaling(localScaling);
|
||||||
|
//buildAccelerator is optional, it may not support all features.
|
||||||
btTriangleInfoMap* triangleInfoMap = new btTriangleInfoMap();
|
heightfieldShape->buildAccelerator();
|
||||||
btGenerateInternalEdgeInfo(heightfieldShape, triangleInfoMap);
|
|
||||||
|
|
||||||
this->m_data->m_heightfieldDatas.push_back(heightfieldData);
|
|
||||||
|
|
||||||
|
if (clientCmd.m_createUserShapeArgs.m_shapes[i].m_collisionFlags & GEOM_CONCAVE_INTERNAL_EDGE)
|
||||||
|
{
|
||||||
|
btTriangleInfoMap* triangleInfoMap = new btTriangleInfoMap();
|
||||||
|
btGenerateInternalEdgeInfo(heightfieldShape, triangleInfoMap);
|
||||||
|
}
|
||||||
|
this->m_data->m_heightfieldDatas.push_back(heightfieldData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ enum MultiThreadedGUIHelperCommunicationEnums
|
|||||||
eGUIHelperChangeTexture,
|
eGUIHelperChangeTexture,
|
||||||
eGUIHelperRemoveTexture,
|
eGUIHelperRemoveTexture,
|
||||||
eGUIHelperSetVisualizerFlagCheckRenderedFrame,
|
eGUIHelperSetVisualizerFlagCheckRenderedFrame,
|
||||||
|
eGUIHelperUpdateShape,
|
||||||
};
|
};
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -865,6 +866,18 @@ public:
|
|||||||
workerThreadWait();
|
workerThreadWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int m_updateShapeIndex;
|
||||||
|
float* m_updateShapeVertices;
|
||||||
|
|
||||||
|
virtual void updateShape(int shapeIndex, float* vertices)
|
||||||
|
{
|
||||||
|
m_updateShapeIndex = shapeIndex;
|
||||||
|
m_updateShapeVertices = vertices;
|
||||||
|
|
||||||
|
m_cs->lock();
|
||||||
|
m_cs->setSharedParam(1, eGUIHelperUpdateShape);
|
||||||
|
workerThreadWait();
|
||||||
|
}
|
||||||
virtual int registerTexture(const unsigned char* texels, int width, int height)
|
virtual int registerTexture(const unsigned char* texels, int width, int height)
|
||||||
{
|
{
|
||||||
int* cachedTexture = m_cachedTextureIds[texels];
|
int* cachedTexture = m_cachedTextureIds[texels];
|
||||||
@@ -1916,6 +1929,15 @@ void PhysicsServerExample::updateGraphics()
|
|||||||
m_multiThreadedHelper->mainThreadRelease();
|
m_multiThreadedHelper->mainThreadRelease();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case eGUIHelperUpdateShape:
|
||||||
|
{
|
||||||
|
B3_PROFILE("eGUIHelperUpdateShape");
|
||||||
|
m_multiThreadedHelper->m_childGuiHelper->updateShape(m_multiThreadedHelper->m_updateShapeIndex, m_multiThreadedHelper->m_updateShapeVertices);
|
||||||
|
m_multiThreadedHelper->mainThreadRelease();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case eGUIHelperRegisterGraphicsShape:
|
case eGUIHelperRegisterGraphicsShape:
|
||||||
{
|
{
|
||||||
B3_PROFILE("eGUIHelperRegisterGraphicsShape");
|
B3_PROFILE("eGUIHelperRegisterGraphicsShape");
|
||||||
@@ -2039,6 +2061,7 @@ void PhysicsServerExample::updateGraphics()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
case eGUIHelperSetVisualizerFlagCheckRenderedFrame:
|
case eGUIHelperSetVisualizerFlagCheckRenderedFrame:
|
||||||
{
|
{
|
||||||
if (m_renderedFrames != m_multiThreadedHelper->m_renderedFrames)
|
if (m_renderedFrames != m_multiThreadedHelper->m_renderedFrames)
|
||||||
|
|||||||
@@ -965,6 +965,7 @@ struct b3CreateUserShapeData
|
|||||||
int m_numHeightfieldColumns;
|
int m_numHeightfieldColumns;
|
||||||
double m_rgbaColor[4];
|
double m_rgbaColor[4];
|
||||||
double m_specularColor[3];
|
double m_specularColor[3];
|
||||||
|
int m_replaceHeightfieldIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_COMPOUND_COLLISION_SHAPES 16
|
#define MAX_COMPOUND_COLLISION_SHAPES 16
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import pybullet as p
|
import pybullet as p
|
||||||
import pybullet_data as pd
|
import pybullet_data as pd
|
||||||
|
import math
|
||||||
import time
|
import time
|
||||||
|
|
||||||
p.connect(p.GUI)
|
p.connect(p.GUI)
|
||||||
@@ -11,6 +11,7 @@ textureId = -1
|
|||||||
useProgrammatic = 0
|
useProgrammatic = 0
|
||||||
useTerrainFromPNG = 1
|
useTerrainFromPNG = 1
|
||||||
useDeepLocoCSV = 2
|
useDeepLocoCSV = 2
|
||||||
|
updateHeightfield = False
|
||||||
|
|
||||||
heightfieldSource = useProgrammatic
|
heightfieldSource = useProgrammatic
|
||||||
import random
|
import random
|
||||||
@@ -30,7 +31,7 @@ if heightfieldSource==useProgrammatic:
|
|||||||
heightfieldData[2*i+1+(2*j+1)*numHeightfieldRows]=height
|
heightfieldData[2*i+1+(2*j+1)*numHeightfieldRows]=height
|
||||||
|
|
||||||
|
|
||||||
terrainShape = p.createCollisionShape(shapeType = p.GEOM_HEIGHTFIELD, meshScale=[.05,.05,1], heightfieldTextureScaling=(numHeightfieldRows-1)/2, heightfieldData=heightfieldData, numHeightfieldRows=numHeightfieldRows, numHeightfieldColumns=numHeightfieldColumns, )
|
terrainShape = p.createCollisionShape(shapeType = p.GEOM_HEIGHTFIELD, meshScale=[.05,.05,1], heightfieldTextureScaling=(numHeightfieldRows-1)/2, heightfieldData=heightfieldData, numHeightfieldRows=numHeightfieldRows, numHeightfieldColumns=numHeightfieldColumns)
|
||||||
terrain = p.createMultiBody(0, terrainShape)
|
terrain = p.createMultiBody(0, terrainShape)
|
||||||
p.resetBasePositionAndOrientation(terrain,[0,0,0], [0,0,0,1])
|
p.resetBasePositionAndOrientation(terrain,[0,0,0], [0,0,0,1])
|
||||||
|
|
||||||
@@ -114,7 +115,23 @@ for i in range(p.getNumJoints(sphereUid)):
|
|||||||
|
|
||||||
|
|
||||||
while (p.isConnected()):
|
while (p.isConnected()):
|
||||||
#keys = p.getKeyboardEvents()
|
keys = p.getKeyboardEvents()
|
||||||
|
|
||||||
|
if updateHeightfield and heightfieldSource==useProgrammatic:
|
||||||
|
for j in range (int(numHeightfieldColumns/2)):
|
||||||
|
for i in range (int(numHeightfieldRows/2) ):
|
||||||
|
height = random.uniform(0,heightPerturbationRange)#+math.sin(time.time())
|
||||||
|
heightfieldData[2*i+2*j*numHeightfieldRows]=height
|
||||||
|
heightfieldData[2*i+1+2*j*numHeightfieldRows]=height
|
||||||
|
heightfieldData[2*i+(2*j+1)*numHeightfieldRows]=height
|
||||||
|
heightfieldData[2*i+1+(2*j+1)*numHeightfieldRows]=height
|
||||||
|
#GEOM_CONCAVE_INTERNAL_EDGE may help avoid getting stuck at an internal (shared) edge of the triangle/heightfield.
|
||||||
|
#GEOM_CONCAVE_INTERNAL_EDGE is a bit slower to build though.
|
||||||
|
#flags = p.GEOM_CONCAVE_INTERNAL_EDGE
|
||||||
|
flags = 0
|
||||||
|
terrainShape2 = p.createCollisionShape(shapeType = p.GEOM_HEIGHTFIELD, flags = flags, meshScale=[.05,.05,1], heightfieldTextureScaling=(numHeightfieldRows-1)/2, heightfieldData=heightfieldData, numHeightfieldRows=numHeightfieldRows, numHeightfieldColumns=numHeightfieldColumns, replaceHeightfieldIndex = terrainShape)
|
||||||
|
|
||||||
|
|
||||||
#print(keys)
|
#print(keys)
|
||||||
#getCameraImage note: software/TinyRenderer doesn't render/support heightfields!
|
#getCameraImage note: software/TinyRenderer doesn't render/support heightfields!
|
||||||
#p.getCameraImage(320,200, renderer=p.ER_BULLET_HARDWARE_OPENGL)
|
#p.getCameraImage(320,200, renderer=p.ER_BULLET_HARDWARE_OPENGL)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
|
//#include "D:/develop/visual_leak_detector/include/vld.h"
|
||||||
#include "../SharedMemory/PhysicsClientC_API.h"
|
#include "../SharedMemory/PhysicsClientC_API.h"
|
||||||
#include "../SharedMemory/PhysicsDirectC_API.h"
|
#include "../SharedMemory/PhysicsDirectC_API.h"
|
||||||
#include "../SharedMemory/SharedMemoryInProcessPhysicsC_API.h"
|
#include "../SharedMemory/SharedMemoryInProcessPhysicsC_API.h"
|
||||||
@@ -7987,7 +7987,7 @@ static PyObject* pybullet_createCollisionShape(PyObject* self, PyObject* args, P
|
|||||||
PyObject* heightfieldDataObj = 0;
|
PyObject* heightfieldDataObj = 0;
|
||||||
int numHeightfieldRows = -1;
|
int numHeightfieldRows = -1;
|
||||||
int numHeightfieldColumns = -1;
|
int numHeightfieldColumns = -1;
|
||||||
|
int replaceHeightfieldIndex = -1;
|
||||||
static char* kwlist[] = {"shapeType",
|
static char* kwlist[] = {"shapeType",
|
||||||
"radius",
|
"radius",
|
||||||
"halfExtents",
|
"halfExtents",
|
||||||
@@ -8004,9 +8004,10 @@ static PyObject* pybullet_createCollisionShape(PyObject* self, PyObject* args, P
|
|||||||
"heightfieldData",
|
"heightfieldData",
|
||||||
"numHeightfieldRows",
|
"numHeightfieldRows",
|
||||||
"numHeightfieldColumns",
|
"numHeightfieldColumns",
|
||||||
|
"replaceHeightfieldIndex",
|
||||||
"physicsClientId", NULL};
|
"physicsClientId", NULL};
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|dOdsOOiOOOOdOiii", kwlist,
|
if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|dOdsOOiOOOOdOiiii", kwlist,
|
||||||
&shapeType, &radius, &halfExtentsObj, &height, &fileName, &meshScaleObj, &planeNormalObj, &flags, &collisionFramePositionObj, &collisionFrameOrientationObj, &verticesObj, &indicesObj, &heightfieldTextureScaling, &heightfieldDataObj, &numHeightfieldRows, &numHeightfieldColumns, &physicsClientId))
|
&shapeType, &radius, &halfExtentsObj, &height, &fileName, &meshScaleObj, &planeNormalObj, &flags, &collisionFramePositionObj, &collisionFrameOrientationObj, &verticesObj, &indicesObj, &heightfieldTextureScaling, &heightfieldDataObj, &numHeightfieldRows, &numHeightfieldColumns, &replaceHeightfieldIndex, &physicsClientId))
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -8053,40 +8054,45 @@ static PyObject* pybullet_createCollisionShape(PyObject* self, PyObject* args, P
|
|||||||
}
|
}
|
||||||
if (shapeType == GEOM_HEIGHTFIELD && fileName==0 && heightfieldDataObj && numHeightfieldColumns>0 && numHeightfieldRows > 0)
|
if (shapeType == GEOM_HEIGHTFIELD && fileName==0 && heightfieldDataObj && numHeightfieldColumns>0 && numHeightfieldRows > 0)
|
||||||
{
|
{
|
||||||
|
PyObject* seqPoints=0;
|
||||||
|
int numHeightfieldPoints;
|
||||||
if (meshScaleObj)
|
if (meshScaleObj)
|
||||||
{
|
{
|
||||||
pybullet_internalSetVectord(meshScaleObj, meshScale);
|
pybullet_internalSetVectord(meshScaleObj, meshScale);
|
||||||
}
|
}
|
||||||
PyObject* seqPoints = PySequence_Fast(heightfieldDataObj, "expected a sequence");
|
seqPoints = PySequence_Fast(heightfieldDataObj, "expected a sequence");
|
||||||
int numHeightfieldPoints = PySequence_Size(heightfieldDataObj);
|
numHeightfieldPoints = PySequence_Size(heightfieldDataObj);
|
||||||
if (numHeightfieldPoints != numHeightfieldColumns*numHeightfieldRows)
|
if (numHeightfieldPoints != numHeightfieldColumns*numHeightfieldRows)
|
||||||
{
|
{
|
||||||
PyErr_SetString(SpamError, "Size of heightfieldData doesn't match numHeightfieldColumns*numHeightfieldRows");
|
PyErr_SetString(SpamError, "Size of heightfieldData doesn't match numHeightfieldColumns*numHeightfieldRows");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyObject* item;
|
|
||||||
int i;
|
|
||||||
float* pointBuffer = (float*)malloc(numHeightfieldPoints*sizeof(float));
|
|
||||||
if (PyList_Check(seqPoints))
|
|
||||||
{
|
{
|
||||||
for (i = 0; i < numHeightfieldPoints; i++)
|
PyObject* item;
|
||||||
|
int i;
|
||||||
|
float* pointBuffer = (float*)malloc(numHeightfieldPoints*sizeof(float));
|
||||||
|
if (PyList_Check(seqPoints))
|
||||||
{
|
{
|
||||||
item = PyList_GET_ITEM(seqPoints, i);
|
for (i = 0; i < numHeightfieldPoints; i++)
|
||||||
pointBuffer[i] = (float)PyFloat_AsDouble(item);
|
{
|
||||||
|
item = PyList_GET_ITEM(seqPoints, i);
|
||||||
|
pointBuffer[i] = (float)PyFloat_AsDouble(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 0; i < numHeightfieldPoints; i++)
|
|
||||||
{
|
{
|
||||||
item = PyTuple_GET_ITEM(seqPoints, i);
|
for (i = 0; i < numHeightfieldPoints; i++)
|
||||||
pointBuffer[i] = (float)PyFloat_AsDouble(item);
|
{
|
||||||
|
item = PyTuple_GET_ITEM(seqPoints, i);
|
||||||
|
pointBuffer[i] = (float)PyFloat_AsDouble(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
shapeIndex = b3CreateCollisionShapeAddHeightfield2(sm, commandHandle, meshScale, heightfieldTextureScaling, pointBuffer, numHeightfieldRows, numHeightfieldColumns, replaceHeightfieldIndex);
|
||||||
|
|
||||||
|
free(pointBuffer);
|
||||||
|
if (seqPoints)
|
||||||
|
Py_DECREF(seqPoints);
|
||||||
}
|
}
|
||||||
shapeIndex = b3CreateCollisionShapeAddHeightfield2(sm, commandHandle, meshScale, heightfieldTextureScaling, pointBuffer, numHeightfieldRows, numHeightfieldColumns);
|
|
||||||
free(pointBuffer);
|
|
||||||
if (seqPoints)
|
|
||||||
Py_DECREF(seqPoints);
|
|
||||||
}
|
}
|
||||||
if (shapeType == GEOM_MESH && fileName)
|
if (shapeType == GEOM_MESH && fileName)
|
||||||
{
|
{
|
||||||
@@ -8141,7 +8147,10 @@ static PyObject* pybullet_createCollisionShape(PyObject* self, PyObject* args, P
|
|||||||
{
|
{
|
||||||
pybullet_internalSetVector4d(collisionFrameOrientationObj, collisionFrameOrientation);
|
pybullet_internalSetVector4d(collisionFrameOrientationObj, collisionFrameOrientation);
|
||||||
}
|
}
|
||||||
b3CreateCollisionShapeSetChildTransform(commandHandle, shapeIndex, collisionFramePosition, collisionFrameOrientation);
|
if (collisionFramePositionObj || collisionFrameOrientationObj)
|
||||||
|
{
|
||||||
|
b3CreateCollisionShapeSetChildTransform(commandHandle, shapeIndex, collisionFramePosition, collisionFrameOrientation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
statusHandle = b3SubmitClientCommandAndWaitStatus(sm, commandHandle);
|
statusHandle = b3SubmitClientCommandAndWaitStatus(sm, commandHandle);
|
||||||
statusType = b3GetStatusType(statusHandle);
|
statusType = b3GetStatusType(statusHandle);
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -485,7 +485,7 @@ if 'BT_USE_EGL' in EGL_CXX_FLAGS:
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='pybullet',
|
name='pybullet',
|
||||||
version='2.5.3',
|
version='2.5.5',
|
||||||
description=
|
description=
|
||||||
'Official Python Interface for the Bullet Physics SDK specialized for Robotics Simulation and Reinforcement Learning',
|
'Official Python Interface for the Bullet Physics SDK specialized for Robotics Simulation and Reinforcement Learning',
|
||||||
long_description=
|
long_description=
|
||||||
|
|||||||
@@ -220,6 +220,10 @@ public:
|
|||||||
{
|
{
|
||||||
m_triangleInfoMap = map;
|
m_triangleInfoMap = map;
|
||||||
}
|
}
|
||||||
|
const unsigned char* getHeightfieldRawData() const
|
||||||
|
{
|
||||||
|
return m_heightfieldDataUnsignedChar;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //BT_HEIGHTFIELD_TERRAIN_SHAPE_H
|
#endif //BT_HEIGHTFIELD_TERRAIN_SHAPE_H
|
||||||
@@ -33,7 +33,7 @@ struct DeformableContactConstraint
|
|||||||
append(rcontact);
|
append(rcontact);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeformableContactConstraint(const btVector3 dir)
|
DeformableContactConstraint(const btVector3& dir)
|
||||||
{
|
{
|
||||||
m_contact.push_back(NULL);
|
m_contact.push_back(NULL);
|
||||||
m_direction.push_back(dir);
|
m_direction.push_back(dir);
|
||||||
|
|||||||
Reference in New Issue
Block a user