b2BuoyancyController.cpp
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:4k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /*
  2. * Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty.  In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. * Permission is granted to anyone to use this software for any purpose,
  8. * including commercial applications, and to alter it and redistribute it
  9. * freely, subject to the following restrictions:
  10. * 1. The origin of this software must not be misrepresented; you must not
  11. * claim that you wrote the original software. If you use this software
  12. * in a product, an acknowledgment in the product documentation would be
  13. * appreciated but is not required.
  14. * 2. Altered source versions must be plainly marked as such, and must not be
  15. * misrepresented as being the original software.
  16. * 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #include "b2BuoyancyController.h"
  19. #include "../b2Fixture.h"
  20. b2BuoyancyController::b2BuoyancyController(const b2BuoyancyControllerDef* def) : b2Controller(def)
  21. {
  22. normal = def->normal;
  23. offset = def->offset;
  24. density = def->density;
  25. velocity = def->velocity;
  26. linearDrag = def->linearDrag;
  27. angularDrag = def->angularDrag;
  28. useDensity = def->useDensity;
  29. useWorldGravity = def->useWorldGravity;
  30. gravity = def->gravity;
  31. }
  32. void b2BuoyancyController::Step(const b2TimeStep& step)
  33. {
  34. B2_NOT_USED(step);
  35. if(!m_bodyList)
  36. return;
  37. if(useWorldGravity)
  38. {
  39. gravity = m_world->GetGravity();
  40. }
  41. for(b2ControllerEdge *i=m_bodyList;i;i=i->nextBody)
  42. {
  43. b2Body* body = i->body;
  44. if(body->IsSleeping())
  45. {
  46. //Buoyancy force is just a function of position,
  47. //so unlike most forces, it is safe to ignore sleeping bodes
  48. continue;
  49. }
  50. b2Vec2 areac(0,0);
  51. b2Vec2 massc(0,0);
  52. float32 area = 0;
  53. float32 mass = 0;
  54. for(b2Fixture* shape=body->GetFixtureList();shape;shape=shape->GetNext())
  55. {
  56. b2Vec2 sc(0,0);
  57. float32 sarea = shape->ComputeSubmergedArea(normal, offset, &sc);
  58. area += sarea;
  59. areac.x += sarea * sc.x;
  60. areac.y += sarea * sc.y;
  61. float shapeDensity = 0;
  62. if(useDensity)
  63. {
  64. //TODO: Expose density publicly
  65. shapeDensity=shape->GetDensity();
  66. }
  67. else
  68. {
  69. shapeDensity = 1;
  70. }
  71. mass += sarea*shapeDensity;
  72. massc.x += sarea * sc.x * shapeDensity;
  73. massc.y += sarea * sc.y * shapeDensity;
  74. }
  75. areac.x/=area;
  76. areac.y/=area;
  77. b2Vec2 localCentroid = b2MulT(body->GetXForm(),areac);
  78. massc.x/=mass;
  79. massc.y/=mass;
  80. if(area<B2_FLT_EPSILON)
  81. continue;
  82. //Buoyancy
  83. b2Vec2 buoyancyForce = -density*area*gravity;
  84. body->ApplyForce(buoyancyForce,massc);
  85. //Linear drag
  86. b2Vec2 dragForce = body->GetLinearVelocityFromWorldPoint(areac) - velocity;
  87. dragForce *= -linearDrag*area;
  88. body->ApplyForce(dragForce,areac);
  89. //Angular drag
  90. //TODO: Something that makes more physical sense?
  91. body->ApplyTorque(-body->GetInertia()/body->GetMass()*area*body->GetAngularVelocity()*angularDrag);
  92. }
  93. }
  94. void b2BuoyancyController::Draw(b2DebugDraw *debugDraw)
  95. {
  96. float32 r = 1000;
  97. b2Vec2 p1 = offset * normal + b2Cross(normal, r);
  98. b2Vec2 p2 = offset * normal - b2Cross(normal, r);
  99. b2Color color(0,0,0.8f);
  100. debugDraw->DrawSegment(p1, p2, color);
  101. }
  102. void b2BuoyancyController::Destroy(b2BlockAllocator* allocator)
  103. {
  104. allocator->Free(this, sizeof(b2BuoyancyController));
  105. }
  106. b2BuoyancyController* b2BuoyancyControllerDef::Create(b2BlockAllocator* allocator) const
  107. {
  108. void* mem = allocator->Allocate(sizeof(b2BuoyancyController));
  109. return new (mem) b2BuoyancyController(this);
  110. }