RaytracerSetup.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. #include "RaytracerSetup.h"
  2. #include "../CommonInterfaces/CommonGraphicsAppInterface.h"
  3. #include "Bullet3Common/b3Quaternion.h"
  4. #include "Bullet3Common/b3AlignedObjectArray.h"
  5. #include "../CommonInterfaces/CommonRenderInterface.h"
  6. #include "../CommonInterfaces/Common2dCanvasInterface.h"
  7. //#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
  8. #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
  9. //#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
  10. //#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
  11. #include "../CommonInterfaces/CommonExampleInterface.h"
  12. #include "LinearMath/btAlignedObjectArray.h"
  13. #include "btBulletCollisionCommon.h"
  14. #include "../CommonInterfaces/CommonGUIHelperInterface.h"
  15. struct RaytracerPhysicsSetup : public CommonExampleInterface
  16. {
  17. struct CommonGraphicsApp* m_app;
  18. struct RaytracerInternalData* m_internalData;
  19. RaytracerPhysicsSetup(struct CommonGraphicsApp* app);
  20. virtual ~RaytracerPhysicsSetup();
  21. virtual void initPhysics();
  22. virtual void exitPhysics();
  23. virtual void stepSimulation(float deltaTime);
  24. virtual void physicsDebugDraw(int debugFlags);
  25. virtual void syncPhysicsToGraphics(struct GraphicsPhysicsBridge& gfxBridge);
  26. ///worldRaytest performs a ray versus all objects in a collision world, returning true is a hit is found (filling in worldNormal and worldHitPoint)
  27. bool worldRaytest(const btVector3& rayFrom,const btVector3& rayTo,btVector3& worldNormal,btVector3& worldHitPoint);
  28. ///singleObjectRaytest performs a ray versus one collision shape, returning true is a hit is found (filling in worldNormal and worldHitPoint)
  29. bool singleObjectRaytest(const btVector3& rayFrom,const btVector3& rayTo,btVector3& worldNormal,btVector3& worldHitPoint);
  30. ///lowlevelRaytest performs a ray versus convex shape, returning true is a hit is found (filling in worldNormal and worldHitPoint)
  31. bool lowlevelRaytest(const btVector3& rayFrom,const btVector3& rayTo,btVector3& worldNormal,btVector3& worldHitPoint);
  32. virtual bool mouseMoveCallback(float x,float y);
  33. virtual bool mouseButtonCallback(int button, int state, float x, float y);
  34. virtual bool keyboardCallback(int key, int state);
  35. virtual void renderScene()
  36. {
  37. }
  38. };
  39. struct RaytracerInternalData
  40. {
  41. int m_canvasIndex;
  42. struct Common2dCanvasInterface* m_canvas;
  43. int m_width;
  44. int m_height;
  45. btAlignedObjectArray<btConvexShape*> m_shapePtr;
  46. btAlignedObjectArray<btTransform> m_transforms;
  47. btVoronoiSimplexSolver m_simplexSolver;
  48. btScalar m_pitch;
  49. btScalar m_roll;
  50. btScalar m_yaw;
  51. RaytracerInternalData()
  52. :m_canvasIndex(-1),
  53. m_canvas(0),
  54. m_roll(0),
  55. m_pitch(0),
  56. m_yaw(0),
  57. #ifdef _DEBUG
  58. m_width(64),
  59. m_height(64)
  60. #else
  61. m_width(128),
  62. m_height(128)
  63. #endif
  64. {
  65. btConeShape* cone = new btConeShape(1,1);
  66. btSphereShape* sphere = new btSphereShape(1);
  67. btBoxShape* box = new btBoxShape (btVector3(1,1,1));
  68. m_shapePtr.push_back(cone);
  69. m_shapePtr.push_back(sphere);
  70. m_shapePtr.push_back(box);
  71. updateTransforms();
  72. }
  73. void updateTransforms()
  74. {
  75. int numObjects = m_shapePtr.size();
  76. m_transforms.resize(numObjects);
  77. for (int i=0;i<numObjects;i++)
  78. {
  79. m_transforms[i].setIdentity();
  80. btVector3 pos(0.f,0.f,-(2.5* numObjects * 0.5)+i*2.5f);
  81. m_transforms[i].setIdentity();
  82. m_transforms[i].setOrigin( pos );
  83. btQuaternion orn;
  84. if (i < 2)
  85. {
  86. orn.setEuler(m_yaw,m_pitch,m_roll);
  87. m_transforms[i].setRotation(orn);
  88. }
  89. }
  90. m_pitch += 0.005f;
  91. m_yaw += 0.01f;
  92. }
  93. };
  94. RaytracerPhysicsSetup::RaytracerPhysicsSetup(struct CommonGraphicsApp* app)
  95. {
  96. m_app = app;
  97. m_internalData = new RaytracerInternalData;
  98. }
  99. RaytracerPhysicsSetup::~RaytracerPhysicsSetup()
  100. {
  101. delete m_internalData;
  102. }
  103. void RaytracerPhysicsSetup::initPhysics()
  104. {
  105. //request a visual bitma/texture we can render to
  106. m_internalData->m_canvas = m_app->m_2dCanvasInterface;
  107. if (m_internalData->m_canvas)
  108. {
  109. m_internalData->m_canvasIndex = m_internalData->m_canvas->createCanvas("raytracer",m_internalData->m_width,m_internalData->m_height);
  110. for (int i=0;i<m_internalData->m_width;i++)
  111. {
  112. for (int j=0;j<m_internalData->m_height;j++)
  113. {
  114. unsigned char red=255;
  115. unsigned char green=255;
  116. unsigned char blue=255;
  117. unsigned char alpha=255;
  118. m_internalData->m_canvas->setPixel(m_internalData->m_canvasIndex,i,j,red,green,blue,alpha);
  119. }
  120. }
  121. m_internalData->m_canvas->refreshImageData(m_internalData->m_canvasIndex);
  122. //int bitmapId = gfxBridge.createRenderBitmap(width,height);
  123. }
  124. }
  125. ///worldRaytest performs a ray versus all objects in a collision world, returning true is a hit is found (filling in worldNormal and worldHitPoint)
  126. bool RaytracerPhysicsSetup::worldRaytest(const btVector3& rayFrom,const btVector3& rayTo,btVector3& worldNormal,btVector3& worldHitPoint)
  127. {
  128. return false;
  129. }
  130. ///singleObjectRaytest performs a ray versus one collision shape, returning true is a hit is found (filling in worldNormal and worldHitPoint)
  131. bool RaytracerPhysicsSetup::singleObjectRaytest(const btVector3& rayFrom,const btVector3& rayTo,btVector3& worldNormal,btVector3& worldHitPoint)
  132. {
  133. return false;
  134. }
  135. ///lowlevelRaytest performs a ray versus convex shape, returning true is a hit is found (filling in worldNormal and worldHitPoint)
  136. bool RaytracerPhysicsSetup::lowlevelRaytest(const btVector3& rayFrom,const btVector3& rayTo,btVector3& worldNormal,btVector3& worldHitPoint)
  137. {
  138. btScalar closestHitResults = 1.f;
  139. bool hasHit = false;
  140. btConvexCast::CastResult rayResult;
  141. btSphereShape pointShape(0.0f);
  142. btTransform rayFromTrans;
  143. btTransform rayToTrans;
  144. rayFromTrans.setIdentity();
  145. rayFromTrans.setOrigin(rayFrom);
  146. rayToTrans.setIdentity();
  147. rayToTrans.setOrigin(rayTo);
  148. int numObjects = m_internalData->m_shapePtr.size();
  149. for (int s=0;s<numObjects;s++)
  150. {
  151. //do some culling, ray versus aabb
  152. btVector3 aabbMin,aabbMax;
  153. m_internalData->m_shapePtr[s]->getAabb( m_internalData->m_transforms[s],aabbMin,aabbMax);
  154. btScalar hitLambda = 1.f;
  155. btVector3 hitNormal;
  156. btCollisionObject tmpObj;
  157. tmpObj.setWorldTransform( m_internalData->m_transforms[s]);
  158. if (btRayAabb(rayFrom,rayTo,aabbMin,aabbMax,hitLambda,hitNormal))
  159. {
  160. //reset previous result
  161. //choose the continuous collision detection method
  162. btSubsimplexConvexCast convexCaster(&pointShape, m_internalData->m_shapePtr[s],&m_internalData->m_simplexSolver);
  163. //btGjkConvexCast convexCaster(&pointShape,shapePtr[s],&simplexSolver);
  164. //btContinuousConvexCollision convexCaster(&pointShape,shapePtr[s],&simplexSolver,0);
  165. if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans, m_internalData->m_transforms[s], m_internalData->m_transforms[s],rayResult))
  166. {
  167. if (rayResult.m_fraction < closestHitResults)
  168. {
  169. closestHitResults = rayResult.m_fraction;
  170. worldNormal = m_internalData->m_transforms[s].getBasis() *rayResult.m_normal;
  171. worldNormal.normalize();
  172. hasHit = true;
  173. }
  174. }
  175. }
  176. }
  177. return hasHit;
  178. }
  179. void RaytracerPhysicsSetup::exitPhysics()
  180. {
  181. if (m_internalData->m_canvas && m_internalData->m_canvasIndex>=0)
  182. {
  183. m_internalData->m_canvas->destroyCanvas(m_internalData->m_canvasIndex);
  184. }
  185. }
  186. void RaytracerPhysicsSetup::stepSimulation(float deltaTime)
  187. {
  188. m_internalData->updateTransforms();
  189. float top = 1.f;
  190. float bottom = -1.f;
  191. float nearPlane = 1.f;
  192. float tanFov = (top-bottom)*0.5f / nearPlane;
  193. float fov = 2.0 * atanf (tanFov);
  194. btVector3 cameraPosition(5,0,0);
  195. btVector3 cameraTargetPosition(0,0,0);
  196. if (m_app->m_renderer && m_app->m_renderer->getActiveCamera())
  197. {
  198. m_app->m_renderer->getActiveCamera()->getCameraPosition(cameraPosition);
  199. m_app->m_renderer->getActiveCamera()->getCameraTargetPosition(cameraTargetPosition);
  200. }
  201. btVector3 rayFrom = cameraPosition;
  202. btVector3 rayForward = cameraTargetPosition-cameraPosition;
  203. rayForward.normalize();
  204. float farPlane = 600.f;
  205. rayForward*= farPlane;
  206. btVector3 rightOffset;
  207. btVector3 vertical(0.f,1.f,0.f);
  208. btVector3 hor;
  209. hor = rayForward.cross(vertical);
  210. hor.normalize();
  211. vertical = hor.cross(rayForward);
  212. vertical.normalize();
  213. float tanfov = tanf(0.5f*fov);
  214. hor *= 2.f * farPlane * tanfov;
  215. vertical *= 2.f * farPlane * tanfov;
  216. btVector3 rayToCenter = rayFrom + rayForward;
  217. btVector3 dHor = hor * 1.f/float(m_internalData->m_width);
  218. btVector3 dVert = vertical * 1.f/float(m_internalData->m_height);
  219. int mode = 0;
  220. int x,y;
  221. for (x=0;x<m_internalData->m_width;x++)
  222. {
  223. for (y=0;y<m_internalData->m_height;y++)
  224. {
  225. btVector4 rgba(0,0,0,0);
  226. btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical;
  227. rayTo += x * dHor;
  228. rayTo -= y * dVert;
  229. btVector3 worldNormal(0,0,0);
  230. btVector3 worldPoint(0,0,0);
  231. bool hasHit = false;
  232. int mode = 0;
  233. switch (mode)
  234. {
  235. case 0:
  236. hasHit = lowlevelRaytest(rayFrom,rayTo,worldNormal,worldPoint);
  237. break;
  238. case 1:
  239. hasHit = singleObjectRaytest(rayFrom,rayTo,worldNormal,worldPoint);
  240. break;
  241. case 2:
  242. hasHit = worldRaytest(rayFrom,rayTo,worldNormal,worldPoint);
  243. break;
  244. default:
  245. {
  246. }
  247. }
  248. if (hasHit)
  249. {
  250. float lightVec0 = worldNormal.dot(btVector3(0,-1,-1));//0.4f,-1.f,-0.4f));
  251. float lightVec1= worldNormal.dot(btVector3(-1,0,-1));//-0.4f,-1.f,-0.4f));
  252. rgba = btVector4(lightVec0,lightVec1,0,1.f);
  253. rgba.setMin(btVector3(1,1,1));
  254. rgba.setMax(btVector3(0.2,0.2,0.2));
  255. rgba[3] = 1.f;
  256. unsigned char red = rgba[0] * 255;
  257. unsigned char green = rgba[1] * 255;
  258. unsigned char blue = rgba[2] * 255;
  259. unsigned char alpha=255;
  260. m_internalData->m_canvas->setPixel(m_internalData->m_canvasIndex,x,y,red,green,blue,alpha);
  261. } else
  262. {
  263. // btVector4 rgba = raytracePicture->getPixel(x,y);
  264. }
  265. if (!rgba.length2())
  266. {
  267. m_internalData->m_canvas->setPixel(m_internalData->m_canvasIndex,x,y,255,0,0,255);
  268. }
  269. }
  270. }
  271. m_internalData->m_canvas->refreshImageData(m_internalData->m_canvasIndex);
  272. }
  273. void RaytracerPhysicsSetup::physicsDebugDraw(int debugDrawFlags)
  274. {
  275. }
  276. bool RaytracerPhysicsSetup::mouseMoveCallback(float x,float y)
  277. {
  278. return false;
  279. }
  280. bool RaytracerPhysicsSetup::mouseButtonCallback(int button, int state, float x, float y)
  281. {
  282. return false;
  283. }
  284. bool RaytracerPhysicsSetup::keyboardCallback(int key, int state)
  285. {
  286. return false;
  287. }
  288. void RaytracerPhysicsSetup::syncPhysicsToGraphics(GraphicsPhysicsBridge& gfxBridge)
  289. {
  290. }
  291. CommonExampleInterface* RayTracerCreateFunc(struct CommonExampleOptions& options)
  292. {
  293. return new RaytracerPhysicsSetup(options.m_guiHelper->getAppInterface());
  294. }