diff --git a/sources/Android.mk b/sources/Android.mk index 522c9b78..65676dc3 100644 --- a/sources/Android.mk +++ b/sources/Android.mk @@ -12,7 +12,7 @@ LOCAL_VERSION=$(shell cat $(LOCAL_PATH)/tag) $(info [TAG:$(LOCAL_MODULE)] $(LOCAL_VERSION)) # name of the dependency -LOCAL_LIBRARIES := etk freetype tinyxml libpng parsersvg lua libzip +LOCAL_LIBRARIES := etk freetype tinyxml libpng parsersvg lua libzip bullet LOCAL_C_INCLUDES := diff --git a/sources/ewol/widget/Scene.cpp b/sources/ewol/widget/Scene.cpp index e72833c9..551ec4f8 100644 --- a/sources/ewol/widget/Scene.cpp +++ b/sources/ewol/widget/Scene.cpp @@ -10,8 +10,29 @@ #include #include #include -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #undef __class__ #define __class__ "Scene" @@ -23,24 +44,238 @@ #define WALK_FLAG_CAUTION (1<<4) +class SceneDebugDrawer : public btIDebugDraw +{ + int m_debugMode; + public: + SceneDebugDrawer():m_debugMode(0) {}; + virtual ~SceneDebugDrawer() {}; + virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& fromColor, const btVector3& toColor) + { + glBegin(GL_LINES); + glColor3f(fromColor.getX(), fromColor.getY(), fromColor.getZ()); + glVertex3d(from.getX(), from.getY(), from.getZ()); + glColor3f(toColor.getX(), toColor.getY(), toColor.getZ()); + glVertex3d(to.getX(), to.getY(), to.getZ()); + glEnd(); + } + virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color) + { + drawLine(from,to,color,color); + } + virtual void drawSphere (const btVector3& p, btScalar radius, const btVector3& color) + { + glColor4f (color.getX(), color.getY(), color.getZ(), btScalar(1.0f)); + glPushMatrix (); + glTranslatef (p.getX(), p.getY(), p.getZ()); + int lats = 5; + int longs = 5; + int i, j; + for(i = 0; i <= lats; i++) { + btScalar lat0 = SIMD_PI * (-btScalar(0.5) + (btScalar) (i - 1) / lats); + btScalar z0 = radius*sin(lat0); + btScalar zr0 = radius*cos(lat0); + btScalar lat1 = SIMD_PI * (-btScalar(0.5) + (btScalar) i / lats); + btScalar z1 = radius*sin(lat1); + btScalar zr1 = radius*cos(lat1); + glBegin(GL_QUAD_STRIP); + for(j = 0; j <= longs; j++) { + btScalar lng = 2 * SIMD_PI * (btScalar) (j - 1) / longs; + btScalar x = cos(lng); + btScalar y = sin(lng); + glNormal3f(x * zr0, y * zr0, z0); + glVertex3f(x * zr0, y * zr0, z0); + glNormal3f(x * zr1, y * zr1, z1); + glVertex3f(x * zr1, y * zr1, z1); + } + glEnd(); + } + glPopMatrix(); + } + + virtual void drawTriangle(const btVector3& a,const btVector3& b,const btVector3& c,const btVector3& color,btScalar alpha) + { + // if (m_debugMode > 0) + { + const btVector3 n=btCross(b-a,c-a).normalized(); + glBegin(GL_TRIANGLES); + glColor4f(color.getX(), color.getY(), color.getZ(),alpha); + glNormal3d(n.getX(),n.getY(),n.getZ()); + glVertex3d(a.getX(),a.getY(),a.getZ()); + glVertex3d(b.getX(),b.getY(),b.getZ()); + glVertex3d(c.getX(),c.getY(),c.getZ()); + glEnd(); + } + } + + + virtual void drawContactPoint(const btVector3& pointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color) + { + btVector3 to=pointOnB+normalOnB*1;//distance; + const btVector3&from = pointOnB; + glColor4f(color.getX(), color.getY(), color.getZ(),1.f); + //glColor4f(0,0,0,1.f); + glBegin(GL_LINES); + glVertex3d(from.getX(), from.getY(), from.getZ()); + glVertex3d(to.getX(), to.getY(), to.getZ()); + glEnd(); + } + + virtual void reportErrorWarning(const char* warningString) + { + printf("%s\n",warningString); + } + + virtual void draw3dText(const btVector3& location,const char* textString) + { + glRasterPos3f(location.x(), location.y(), location.z()); + //BMF_DrawString(BMF_GetFont(BMF_kHelvetica10),textString); + } + + virtual void setDebugMode(int debugMode) + { + m_debugMode = debugMode; + } + + virtual int getDebugMode() const + { + return m_debugMode; + } + +}; + + +SceneDebugDrawer completeDebugger; + + +///create 125 (5x5x5) dynamic object +#define ARRAY_SIZE_X 2 +#define ARRAY_SIZE_Y 2 +#define ARRAY_SIZE_Z 2 + +//maximum number of objects (and allow user to shoot additional boxes) +#define MAX_PROXIES (ARRAY_SIZE_X*ARRAY_SIZE_Y*ARRAY_SIZE_Z + 1024) + +///scaling of the objects (0.1 = 20 centimeter boxes ) +#define SCALING 1. +#define START_POS_X -5 +#define START_POS_Y -5 +#define START_POS_Z -3 + widget::Scene::Scene(btDynamicsWorld* gameEngine) : m_dynamicsWorld(NULL), m_camera(vec3(-6,0,2), vec3(0,0,0)), //m_gameEngine(gameEngine), m_isRunning(true), m_lastCallTime(-1), - m_walk(0) + m_walk(0), + m_debugMode(0), + m_textureinitialized(false), + m_textureenabled(true) { +m_texturehandle = 0; SetCanHaveFocus(true); PeriodicCallSet(true); m_zoom = 1.0/1000.0; m_ratioTime = 1.0f; + + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + ///use the default collision dispatcher. + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + + m_broadphase = new btDbvtBroadphase(); + + ///the default constraint solver. + btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; + m_solver = sol; + + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld->setDebugDrawer(&completeDebugger); + m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + + + // Create The ground + btBoxShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + m_collisionShapes.PushBack(groundShape); + + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0,-50,0)); + btScalar mass(0.0); + btVector3 localInertia(0,0,0); + //rigidbody is dynamic if and only if mass is non zero, otherwise static + if (mass != 0.0f) { + groundShape->calculateLocalInertia(mass, localInertia); + } + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody* body = new btRigidBody(rbInfo); + //add the body to the dynamics world + m_dynamicsWorld->addRigidBody(body); + + + { + // Create a few dynamic rigidbodies + // Re-using the same collision is better for memory usage and performance + btBoxShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,SCALING*1)); + //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); + m_collisionShapes.PushBack(colShape); + /// Create Dynamic Objects + btTransform startTransform; + startTransform.setIdentity(); + btScalar mass(1.0f); + btVector3 localInertia(0,0,0); + //rigidbody is dynamic if and only if mass is non zero, otherwise static + if (mass != 0.0f) { + colShape->calculateLocalInertia(mass, localInertia); + } + float start_x = START_POS_X - ARRAY_SIZE_X/2; + float start_y = START_POS_Y; + float start_z = START_POS_Z - ARRAY_SIZE_Z/2; + for (int kkk=0 ; kkkaddRigidBody(body); + } + } + } + } } widget::Scene::~Scene(void) { - + //cleanup in the reverse order of creation/initialization + //remove the rigidbodies from the dynamics world and delete them + for (int32_t iii=m_dynamicsWorld->getNumCollisionObjects()-1; iii>=0 ;iii--) { + btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[iii]; + btRigidBody* body = btRigidBody::upcast(obj); + if (body && body->getMotionState()) { + delete body->getMotionState(); + } + m_dynamicsWorld->removeCollisionObject( obj ); + delete obj; + } + + //delete collision shapes + for (int jjj=0;jjjgetShapeType() == CUSTOM_CONVEX_SHAPE_TYPE) { + EWOL_DEBUG("Draw : CUSTOM_CONVEX_SHAPE_TYPE"); + btVector3 org(m[12], m[13], m[14]); + btVector3 dx(m[0], m[1], m[2]); + btVector3 dy(m[4], m[5], m[6]); + const btBoxShape* boxShape = static_cast(shape); + btVector3 halfExtent = boxShape->getHalfExtentsWithMargin(); + dx *= halfExtent[0]; + dy *= halfExtent[1]; + glColor3f(1,1,1); + glDisable(GL_LIGHTING); + glLineWidth(2); + glBegin(GL_LINE_LOOP); + glDrawVector(org - dx - dy); + glDrawVector(org - dx + dy); + glDrawVector(org + dx + dy); + glDrawVector(org + dx - dy); + glEnd(); + return; + } else if((shape->getShapeType() == BOX_SHAPE_PROXYTYPE) && (debugMode & btIDebugDraw::DBG_FastWireframe)) { + EWOL_DEBUG("Draw : BOX_SHAPE_PROXYTYPE"); + btVector3 org(m[12], m[13], m[14]); + btVector3 dx(m[0], m[1], m[2]); + btVector3 dy(m[4], m[5], m[6]); + btVector3 dz(m[8], m[9], m[10]); + const btBoxShape* boxShape = static_cast(shape); + btVector3 halfExtent = boxShape->getHalfExtentsWithMargin(); + dx *= halfExtent[0]; + dy *= halfExtent[1]; + dz *= halfExtent[2]; + glBegin(GL_LINE_LOOP); + glDrawVector(org - dx - dy - dz); + glDrawVector(org + dx - dy - dz); + glDrawVector(org + dx + dy - dz); + glDrawVector(org - dx + dy - dz); + glDrawVector(org - dx + dy + dz); + glDrawVector(org + dx + dy + dz); + glDrawVector(org + dx - dy + dz); + glDrawVector(org - dx - dy + dz); + glEnd(); + glBegin(GL_LINES); + glDrawVector(org + dx - dy - dz); + glDrawVector(org + dx - dy + dz); + glDrawVector(org + dx + dy - dz); + glDrawVector(org + dx + dy + dz); + glDrawVector(org - dx - dy - dz); + glDrawVector(org - dx + dy - dz); + glDrawVector(org - dx - dy + dz); + glDrawVector(org - dx + dy + dz); + glEnd(); + return; + } + glPushMatrix(); + glMultMatrixf(m); + if (shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE) { + EWOL_DEBUG("Draw : UNIFORM_SCALING_SHAPE_PROXYTYPE"); + const btUniformScalingShape* scalingShape = static_cast(shape); + const btConvexShape* convexShape = scalingShape->getChildShape(); + float scalingFactor = (float)scalingShape->getUniformScalingFactor(); + { + btScalar tmpScaling[4][4]={{scalingFactor,0,0,0}, + {0,scalingFactor,0,0}, + {0,0,scalingFactor,0}, + {0,0,0,1}}; + DrawOpenGL((btScalar*)tmpScaling, + convexShape, + color, + debugMode, + worldBoundsMin, + worldBoundsMax); + } + glPopMatrix(); + return; + } + if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) { + EWOL_DEBUG("Draw : COMPOUND_SHAPE_PROXYTYPE"); + const btCompoundShape* compoundShape = static_cast(shape); + for (int32_t iii=compoundShape->getNumChildShapes()-1;iii>=0;iii--) { + btTransform childTrans = compoundShape->getChildTransform(iii); + const btCollisionShape* colShape = compoundShape->getChildShape(iii); + ATTRIBUTE_ALIGNED16(btScalar) childMat[16]; + childTrans.getOpenGLMatrix(childMat); + DrawOpenGL(childMat, + colShape, + color, + debugMode, + worldBoundsMin, + worldBoundsMax); + } + } else { + EWOL_DEBUG("Draw : !=COMPOUND_SHAPE_PROXYTYPE"); + /* + if(m_textureenabled&&(!m_textureinitialized)) { + GLubyte* image=new GLubyte[256*256*3]; + for(int y=0;y<256;++y) { + const int t=y>>4; + GLubyte* pi=image+y*256*3; + for(int x=0;x<256;++x) { + const int s=x>>4; + const GLubyte b=180; + GLubyte c=b+((s+t&1)&1)*(255-b); + pi[0]=pi[1]=pi[2]=c;pi+=3; + } + } + glGenTextures(1,(GLuint*)&m_texturehandle); + glBindTexture(GL_TEXTURE_2D,m_texturehandle); + glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR_MIPMAP_LINEAR); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); + glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); + gluBuild2DMipmaps(GL_TEXTURE_2D,3,256,256,GL_RGB,GL_UNSIGNED_BYTE,image); + delete[] image; + }*/ + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glScalef(0.025f,0.025f,0.025f); + glMatrixMode(GL_MODELVIEW); + static const GLfloat planex[]={1,0,0,0}; + // static const GLfloat planey[]={0,1,0,0}; + static const GLfloat planez[]={0,0,1,0}; + glTexGenfv(GL_S,GL_OBJECT_PLANE,planex); + glTexGenfv(GL_T,GL_OBJECT_PLANE,planez); + glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); + glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + + //m_textureinitialized=true; + glEnable(GL_COLOR_MATERIAL); + /*if(m_textureenabled) { + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D,m_texturehandle); + } else { + */ + glDisable(GL_TEXTURE_2D); + //} + glColor3f(color.x(),color.y(), color.z()); + bool useWireframeFallback = true; + if (!(debugMode & btIDebugDraw::DBG_DrawWireframe)) { + EWOL_DEBUG("Draw : !btIDebugDraw::DBG_DrawWireframe"); + ///you can comment out any of the specific cases, and use the default + ///the benefit of 'default' is that it approximates the actual collision shape including collision margin + //int shapetype=m_textureenabled?MAX_BROADPHASE_COLLISION_TYPES:shape->getShapeType(); + int shapetype=shape->getShapeType(); + switch (shapetype) { + case SPHERE_SHAPE_PROXYTYPE: + { + const btSphereShape* sphereShape = static_cast(shape); + float radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin + DrawSphere(radius,10,10); + useWireframeFallback = false; + break; + } + case BOX_SHAPE_PROXYTYPE: + { + const btBoxShape* boxShape = static_cast(shape); + btVector3 halfExtent = boxShape->getHalfExtentsWithMargin(); + static int indices[36] = { + 0,1,2, + 3,2,1, + 4,0,6, + 6,0,2, + 5,1,4, + 4,1,0, + 7,3,1, + 7,1,5, + 5,4,7, + 7,4,6, + 7,2,3, + 7,6,2}; + btVector3 vertices[8]={ + btVector3(halfExtent[0],halfExtent[1],halfExtent[2]), + btVector3(-halfExtent[0],halfExtent[1],halfExtent[2]), + btVector3(halfExtent[0],-halfExtent[1],halfExtent[2]), + btVector3(-halfExtent[0],-halfExtent[1],halfExtent[2]), + btVector3(halfExtent[0],halfExtent[1],-halfExtent[2]), + btVector3(-halfExtent[0],halfExtent[1],-halfExtent[2]), + btVector3(halfExtent[0],-halfExtent[1],-halfExtent[2]), + btVector3(-halfExtent[0],-halfExtent[1],-halfExtent[2])}; + glBegin (GL_TRIANGLES); + int si=36; + for (int32_t iii=0;iii(shape); + btScalar planeConst = staticPlaneShape->getPlaneConstant(); + const btVector3& planeNormal = staticPlaneShape->getPlaneNormal(); + btVector3 planeOrigin = planeNormal * planeConst; + btVector3 vec0,vec1; + btPlaneSpace1(planeNormal,vec0,vec1); + btScalar vecLen = 100.f; + btVector3 pt0 = planeOrigin + vec0*vecLen; + btVector3 pt1 = planeOrigin - vec0*vecLen; + btVector3 pt2 = planeOrigin + vec1*vecLen; + btVector3 pt3 = planeOrigin - vec1*vecLen; + glBegin(GL_LINES); + glVertex3f(pt0.getX(),pt0.getY(),pt0.getZ()); + glVertex3f(pt1.getX(),pt1.getY(),pt1.getZ()); + glVertex3f(pt2.getX(),pt2.getY(),pt2.getZ()); + glVertex3f(pt3.getX(),pt3.getY(),pt3.getZ()); + glEnd(); + break; + } + case MULTI_SPHERE_SHAPE_PROXYTYPE: + { + const btMultiSphereShape* multiSphereShape = static_cast(shape); + btTransform childTransform; + childTransform.setIdentity(); + + for (int32_t iii = multiSphereShape->getSphereCount()-1; iii>=0;iii--) { + btSphereShape sc(multiSphereShape->getSphereRadius(iii)); + childTransform.setOrigin(multiSphereShape->getSpherePosition(iii)); + ATTRIBUTE_ALIGNED16(btScalar) childMat[16]; + childTransform.getOpenGLMatrix(childMat); + DrawOpenGL(childMat, + &sc, + color, + debugMode, + worldBoundsMin, + worldBoundsMax); + } + break; + } + default: + { + if (shape->isConvex()) { + const btConvexPolyhedron* poly = shape->isPolyhedral() ? ((btPolyhedralConvexShape*) shape)->getConvexPolyhedron() : 0; + if (NULL!=poly) { + glBegin(GL_TRIANGLES); + for (int32_t iii=0 ; iiim_faces.size() ; iii++) { + btVector3 centroid(0,0,0); + int numVerts = poly->m_faces[iii].m_indices.size(); + if (numVerts>2) { + btVector3 v1 = poly->m_vertices[poly->m_faces[iii].m_indices[0]]; + for (int32_t vvv=0;vvvm_faces[iii].m_indices.size()-2;vvv++) { + btVector3 v2 = poly->m_vertices[poly->m_faces[iii].m_indices[vvv+1]]; + btVector3 v3 = poly->m_vertices[poly->m_faces[iii].m_indices[vvv+2]]; + btVector3 normal = (v3-v1).cross(v2-v1); + normal.normalize (); + glNormal3f(normal.getX(),normal.getY(),normal.getZ()); + glVertex3f (v1.x(), v1.y(), v1.z()); + glVertex3f (v2.x(), v2.y(), v2.z()); + glVertex3f (v3.x(), v3.y(), v3.z()); + } + } + } + glEnd(); + } else { + // TODO : Set it back ... + /* + ShapeCache* sc=cache((btConvexShape*)shape); + //glutSolidCube(1.0); + btShapeHull* hull = &sc->m_shapehull; + if (hull->numTriangles () > 0) { + int index = 0; + const unsigned int* idx = hull->getIndexPointer(); + const btVector3* vtx = hull->getVertexPointer(); + glBegin (GL_TRIANGLES); + for (int i = 0; i < hull->numTriangles (); i++) { + int i1 = index++; + int i2 = index++; + int i3 = index++; + btAssert(i1 < hull->numIndices () && + i2 < hull->numIndices () && + i3 < hull->numIndices ()); + int index1 = idx[i1]; + int index2 = idx[i2]; + int index3 = idx[i3]; + btAssert(index1 < hull->numVertices () && + index2 < hull->numVertices () && + index3 < hull->numVertices ()); + btVector3 v1 = vtx[index1]; + btVector3 v2 = vtx[index2]; + btVector3 v3 = vtx[index3]; + btVector3 normal = (v3-v1).cross(v2-v1); + normal.normalize (); + glNormal3f(normal.getX(),normal.getY(),normal.getZ()); + glVertex3f (v1.x(), v1.y(), v1.z()); + glVertex3f (v2.x(), v2.y(), v2.z()); + glVertex3f (v3.x(), v3.y(), v3.z()); + } + glEnd (); + } + */ + } + } + } + } + } + glNormal3f(0,1,0); + /// for polyhedral shapes + if (debugMode==btIDebugDraw::DBG_DrawFeaturesText && (shape->isPolyhedral())) { + btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape; + glColor3f(1.f, 1.f, 1.f); + for (int32_t iii=0 ; iiigetNumVertices() ; iii++) { + btVector3 vtx; + polyshape->getVertex(iii, vtx); + } + for (int32_t iii=0 ; iiigetNumPlanes() ; iii++) { + btVector3 normal; + btVector3 vtx; + polyshape->getPlane(normal,vtx,iii); + } + } + } +} + +void DrawShadow(btScalar* m, + const btVector3& extrusion, + const btCollisionShape* shape, + const btVector3& worldBoundsMin, + const btVector3& worldBoundsMax) +{ + glPushMatrix(); + glMultMatrixf(m); + if(shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE) { + const btUniformScalingShape* scalingShape = static_cast(shape); + const btConvexShape* convexShape = scalingShape->getChildShape(); + float scalingFactor = (float)scalingShape->getUniformScalingFactor(); + btScalar tmpScaling[4][4]={ {scalingFactor,0,0,0}, + {0,scalingFactor,0,0}, + {0,0,scalingFactor,0}, + {0,0,0,1}}; + DrawShadow((btScalar*)tmpScaling, + extrusion, + convexShape, + worldBoundsMin, + worldBoundsMax); + glPopMatrix(); + return; + } else if(shape->getShapeType()==COMPOUND_SHAPE_PROXYTYPE) { + const btCompoundShape* compoundShape = static_cast(shape); + for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--) { + btTransform childTrans = compoundShape->getChildTransform(i); + const btCollisionShape* colShape = compoundShape->getChildShape(i); + ATTRIBUTE_ALIGNED16(btScalar) childMat[16]; + childTrans.getOpenGLMatrix(childMat); + DrawShadow(childMat, + extrusion*childTrans.getBasis(), + colShape, + worldBoundsMin, + worldBoundsMax); + } + } else { + if (shape->isConvex()) { + // TODO : Set it back ... + /* + ShapeCache* sc=cache((btConvexShape*)shape); + btShapeHull* hull =&sc->m_shapehull; + glBegin(GL_QUADS); + for(int32_t iii=0 ; iiim_edges.size() ; ++ii) { + const btScalar d=btDot(sc->m_edges[iii].n[0],extrusion); + if((d*btDot(sc->m_edges[iii].n[1],extrusion))<0) { + const int q= d<0?1:0; + const btVector3& a= hull->getVertexPointer()[sc->m_edges[iii].v[q]]; + const btVector3& b= hull->getVertexPointer()[sc->m_edges[iii].v[1-q]]; + glVertex3f(a[0],a[1],a[2]); + glVertex3f(b[0],b[1],b[2]); + glVertex3f(b[0]+extrusion[0],b[1]+extrusion[1],b[2]+extrusion[2]); + glVertex3f(a[0]+extrusion[0],a[1]+extrusion[1],a[2]+extrusion[2]); + } + } + */ + glEnd(); + } + } + if (shape->isConcave()) { + // TODO : Set it back ... + /* + btConcaveShape* concaveMesh = (btConcaveShape*) shape; + GlDrawcallback drawCallback; + drawCallback.m_wireframe = false; + concaveMesh->processAllTriangles(&drawCallback,worldBoundsMin,worldBoundsMax); + */ + } + glPopMatrix(); + +} + + +void widget::Scene::renderscene(int pass) +{ + glPushMatrix(); + EWOL_DEBUG("Render Scene pass=" << pass); + mat4& myMatrix = ewol::openGL::GetMatrix(); + myMatrix = m_camera.GetMatrix() * myMatrix; + myMatrix.Transpose(); + glLoadMatrixf(myMatrix.m_mat); + btScalar mmm[16]; btMatrix3x3 rot; rot.setIdentity(); const int32_t numObjects=m_dynamicsWorld->getNumCollisionObjects(); btVector3 wireColor(1,0,0); for(int32_t iii=0;iiigetCollisionObjectArray()[iii]; btRigidBody* body=btRigidBody::upcast(colObj); if( NULL != body && body->getMotionState() ) { btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); - myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m); + myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(mmm); rot=myMotionState->m_graphicsWorldTrans.getBasis(); } else { - colObj->getWorldTransform().getOpenGLMatrix(m); + colObj->getWorldTransform().getOpenGLMatrix(mmm); rot=colObj->getWorldTransform().getBasis(); } btVector3 wireColor(1.f,1.0f,0.5f); //wants deactivation @@ -122,47 +797,137 @@ void widget::Scene::::renderscene(int pass) aabbMin-=btVector3(BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); aabbMax+=btVector3(BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); - - if (!(getDebugMode()& btIDebugDraw::DBG_DrawWireframe)) + btVector3 m_sundirection(btVector3(1,-2,1)*1000); + if (!(m_debugMode & btIDebugDraw::DBG_DrawWireframe)) { switch(pass) { case 0: - m_shapeDrawer->drawOpenGL(m, - colObj->getCollisionShape(), - wireColor, - getDebugMode(), - aabbMin, - aabbMax); + DrawOpenGL(mmm, + colObj->getCollisionShape(), + wireColor, + m_debugMode, + aabbMin, + aabbMax); break; case 1: - m_shapeDrawer->drawShadow(m, - m_sundirection*rot, - colObj->getCollisionShape(), - aabbMin, - aabbMax); + DrawShadow(mmm, + m_sundirection*rot, + colObj->getCollisionShape(), + aabbMin, + aabbMax); break; case 2: - m_shapeDrawer->drawOpenGL(m, - colObj->getCollisionShape(), - wireColor*btScalar(0.3), - 0, - aabbMin, - aabbMax); + DrawOpenGL(mmm, + colObj->getCollisionShape(), + wireColor*btScalar(0.3), + 0, + aabbMin, + aabbMax); break; } } } + glPopMatrix(); } -*/ + void widget::Scene::OnDraw(ewol::DrawProperty& displayProp) { -/* - if (NULL != m_gameEngine) { - m_gameEngine->Draw(displayProp); + if (m_dynamicsWorld) { + /* + GLfloat light_ambient[] = { btScalar(0.2), btScalar(0.2), btScalar(0.2), btScalar(1.0) }; + GLfloat light_diffuse[] = { btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0) }; + GLfloat light_specular[] = { btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0 )}; + // light_position is NOT default value + GLfloat light_position0[] = { btScalar(1.0), btScalar(10.0), btScalar(1.0), btScalar(0.0 )}; + GLfloat light_position1[] = { btScalar(-1.0), btScalar(-10.0), btScalar(-1.0), btScalar(0.0) }; + + glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); + glLightfv(GL_LIGHT0, GL_POSITION, light_position0); + + glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient); + glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse); + glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular); + glLightfv(GL_LIGHT1, GL_POSITION, light_position1); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + + + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + */ + //updateCamera(); + if(false/*m_enableshadows*/) { + /* + glClear(GL_STENCIL_BUFFER_BIT); + glEnable(GL_CULL_FACE); + renderscene(0); + + glDisable(GL_LIGHTING); + glDepthMask(GL_FALSE); + glDepthFunc(GL_LEQUAL); + glEnable(GL_STENCIL_TEST); + glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); + glStencilFunc(GL_ALWAYS,1,0xFFFFFFFFL); + glFrontFace(GL_CCW); + glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); + renderscene(1); + glFrontFace(GL_CW); + glStencilOp(GL_KEEP,GL_KEEP,GL_DECR); + renderscene(1); + glFrontFace(GL_CCW); + + glPolygonMode(GL_FRONT,GL_FILL); + glPolygonMode(GL_BACK,GL_FILL); + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glEnable(GL_LIGHTING); + glDepthMask(GL_TRUE); + glCullFace(GL_BACK); + glFrontFace(GL_CCW); + glEnable(GL_CULL_FACE); + glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); + + glDepthFunc(GL_LEQUAL); + glStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFFL ); + glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); + glDisable(GL_LIGHTING); + renderscene(2); + glEnable(GL_LIGHTING); + glDepthFunc(GL_LESS); + glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); + */ + } else { + //glDisable(GL_CULL_FACE); + renderscene(0); + } + /* + int32_t xOffset = 10; + int32_t yStart = 20; + int32_t yIncr = 20; + glDisable(GL_LIGHTING); + + glColor3f(0, 0, 0); + if ((m_debugMode & btIDebugDraw::DBG_NoHelpText)==0) { + setOrthographicProjection(); + showProfileInfo(xOffset,yStart,yIncr); + resetPerspectiveProjection(); + } + glDisable(GL_LIGHTING); + */ + //updateCamera(); + + // only for the bebug : + m_dynamicsWorld->debugDrawWorld(); } -*/ } #define WALK_FLAG_FORWARD (1<<0) @@ -196,6 +961,14 @@ void widget::Scene::PeriodicCall(int64_t localTime) // cut the processing in small slot of time to prevent error in the real-time Display (Android call us between 30 to 60 fps) float deltaTime = (float) (curentTime - m_lastCallTime); //EWOL_DEBUG("Time: m_lastCallTime=" << m_lastCallTime << " deltaTime=" << deltaTime); + + ///step the simulation + if (m_dynamicsWorld) + { + m_dynamicsWorld->stepSimulation(deltaTime); + //optional but useful: debug drawing + m_dynamicsWorld->debugDrawWorld(); + } /* if (NULL != m_gameEngine) { if (true == m_isRunning) { diff --git a/sources/ewol/widget/Scene.h b/sources/ewol/widget/Scene.h index aeab3639..a3cf0fa9 100644 --- a/sources/ewol/widget/Scene.h +++ b/sources/ewol/widget/Scene.h @@ -17,21 +17,41 @@ #include #include #include +#include +class btBroadphaseInterface; +class btCollisionShape; +class btOverlappingPairCache; +class btCollisionDispatcher; +class btConstraintSolver; +struct btCollisionAlgorithmCreateFunc; +class btDefaultCollisionConfiguration; class btDynamicsWorld; +#include +class btVector3; namespace widget { class Scene :public ewol::Widget { protected: ///this is the most important class - btDynamicsWorld* m_dynamicsWorld; + btDefaultCollisionConfiguration* m_collisionConfiguration; + btCollisionDispatcher* m_dispatcher; + btBroadphaseInterface* m_broadphase; + btConstraintSolver* m_solver; + btDynamicsWorld* m_dynamicsWorld; + //keep the collision shapes, for deletion/cleanup + etk::Vector m_collisionShapes; game::Camera m_camera; //!< Display point of view //game::Engine* m_gameEngine; //!< display engine system bool m_isRunning; //!< the display is running (not in pause) double m_lastCallTime; //!< previous call Time float m_ratioTime; //!< Ratio time for the speed of the game ... uint32_t m_walk; //!< Wolk properties + int32_t m_debugMode; + bool m_textureinitialized; + bool m_textureenabled; + unsigned int m_texturehandle; public: /** * @brief Main scene constructor @@ -98,6 +118,13 @@ namespace widget { virtual void OnGetFocus(void); // Derived function virtual void OnLostFocus(void); + void renderscene(int pass); + void DrawOpenGL(btScalar* m, + const btCollisionShape* shape, + const btVector3& color, + int32_t debugMode, + const btVector3& worldBoundsMin, + const btVector3& worldBoundsMax); }; };