Main.cpp 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. // Copyright (C) 2009-2018, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <cstdio>
  6. #include "../common/Framework.h"
  7. using namespace anki;
  8. static Error createDestructionEvent(SceneNode* node)
  9. {
  10. CString script = R"(
  11. function update(event, prevTime, crntTime)
  12. -- Do nothing
  13. return 1
  14. end
  15. function onKilled(event, prevTime, crntTime)
  16. logi(string.format("Will kill %s", event:getAssociatedSceneNodes():getAt(0):getName()))
  17. event:getAssociatedSceneNodes():getAt(0):setMarkedForDeletion()
  18. return 1
  19. end
  20. )";
  21. ScriptEvent* event;
  22. ANKI_CHECK(node->getSceneGraph().getEventManager().newEvent(event, -1, 10.0, script));
  23. event->addAssociatedSceneNode(node);
  24. return Error::NONE;
  25. }
  26. class RayCast : public PhysicsWorldRayCastCallback
  27. {
  28. public:
  29. Vec3 m_hitPosition = Vec3(MAX_F32);
  30. Vec3 m_hitNormal;
  31. Bool m_hit = false;
  32. RayCast(Vec3 from, Vec3 to, PhysicsMaterialBit mtl)
  33. : PhysicsWorldRayCastCallback(from, to, mtl)
  34. {
  35. }
  36. void processResult(PhysicsFilteredObject& obj, const Vec3& worldNormal, const Vec3& worldPosition)
  37. {
  38. if((m_from - m_to).dot(worldNormal) < 0.0f)
  39. {
  40. return;
  41. }
  42. if((worldPosition - m_from).getLengthSquared() > (m_hitPosition - m_from).getLengthSquared())
  43. {
  44. return;
  45. }
  46. m_hitPosition = worldPosition;
  47. m_hitNormal = worldNormal;
  48. m_hit = true;
  49. }
  50. };
  51. class MyApp : public SampleApp
  52. {
  53. public:
  54. Error sampleExtraInit() override;
  55. Error userMainLoop(Bool& quit) override;
  56. };
  57. Error MyApp::sampleExtraInit()
  58. {
  59. ScriptResourcePtr script;
  60. ANKI_CHECK(getResourceManager().loadResource("assets/scene.lua", script));
  61. ANKI_CHECK(getScriptManager().evalString(script->getSource()));
  62. // Create the player
  63. if(1)
  64. {
  65. SceneNode& cam = getSceneGraph().getActiveCameraNode();
  66. cam.getComponent<MoveComponent>().setLocalTransform(
  67. Transform(Vec4(0.0, 0.0, 5.0, 0.0), Mat3x4::getIdentity(), 1.0));
  68. PlayerNode* player;
  69. ANKI_CHECK(getSceneGraph().newSceneNode("player", player, Vec4(0.0f, 2.5f, 0.0f, 0.0f)));
  70. PlayerControllerComponent& pcomp = player->getComponent<PlayerControllerComponent>();
  71. pcomp.getPhysicsPlayerController()->setMaterialMask(PhysicsMaterialBit::STATIC_GEOMETRY);
  72. player->addChild(&cam);
  73. }
  74. // Create a body component with joint
  75. {
  76. ModelNode* monkey;
  77. ANKI_CHECK(
  78. getSceneGraph().newSceneNode<ModelNode>("monkey_p2p", monkey, "assets/Suzannedynamic-material.ankimdl"));
  79. BodyNode* body;
  80. ANKI_CHECK(getSceneGraph().newSceneNode<BodyNode>("bmonkey_p2p", body, "assets/Suzanne.ankicl"));
  81. body->getComponent<BodyComponent>().setTransform(
  82. Transform(Vec4(-0.0f, 4.0f, -3.0f, 0.0f), Mat3x4::getIdentity(), 1.0f));
  83. body->addChild(monkey);
  84. body->getComponent<JointComponent>().newHingeJoint(Vec3(0.2f, 1.0f, 0.0f), Vec3(1, 0, 0));
  85. }
  86. // Create a chain
  87. {
  88. const U LINKS = 5;
  89. BodyNode* prevBody = nullptr;
  90. for(U i = 0; i < LINKS; ++i)
  91. {
  92. ModelNode* monkey;
  93. ANKI_CHECK(getSceneGraph().newSceneNode<ModelNode>(
  94. StringAuto(getAllocator()).sprintf("monkey_chain%u", i).toCString(),
  95. monkey,
  96. "assets/Suzannedynamic-material.ankimdl"));
  97. Transform trf(Vec4(-4.3f, 12.0f, -3.0f, 0.0f), Mat3x4::getIdentity(), 1.0f);
  98. trf.getOrigin().y() -= i * 1.25f;
  99. // trf.getOrigin().x() -= i * 0.25f;
  100. // monkey->getComponent<MoveComponent>().setLocalTransform(trf);
  101. BodyNode* body;
  102. ANKI_CHECK(getSceneGraph().newSceneNode<BodyNode>(
  103. StringAuto(getAllocator()).sprintf("bmonkey_chain%u", i).toCString(), body, "assets/Suzanne.ankicl"));
  104. body->getComponent<BodyComponent>().setTransform(trf);
  105. // Create joint
  106. JointComponent& jointc = body->getComponent<JointComponent>();
  107. if(prevBody == nullptr)
  108. {
  109. jointc.newPoint2PointJoint(Vec3(0, 1, 0));
  110. }
  111. else
  112. {
  113. prevBody->addChild(body);
  114. jointc.newPoint2PointJoint2(Vec3(0, 1.0, 0), Vec3(0, -1.0, 0));
  115. }
  116. body->addChild(monkey);
  117. prevBody = body;
  118. }
  119. }
  120. // Trigger
  121. {
  122. TriggerNode* node;
  123. ANKI_CHECK(getSceneGraph().newSceneNode("trigger", node, 1.8f));
  124. node->getComponent<MoveComponent>().setLocalOrigin(Vec4(1.0f, 0.5f, 0.0f, 0.0f));
  125. }
  126. return Error::NONE;
  127. }
  128. Error MyApp::userMainLoop(Bool& quit)
  129. {
  130. // ANKI_CHECK(SampleApp::userMainLoop(quit));
  131. if(getInput().getKey(KeyCode::ESCAPE))
  132. {
  133. quit = true;
  134. }
  135. if(getInput().getKey(KeyCode::F1) == 1)
  136. {
  137. static U mode = 0;
  138. mode = (mode + 1) % 3;
  139. if(mode == 0)
  140. {
  141. getMainRenderer().getDbg().setEnabled(false);
  142. }
  143. else if(mode == 1)
  144. {
  145. getMainRenderer().getDbg().setEnabled(true);
  146. getMainRenderer().getDbg().setDepthTestEnabled(true);
  147. getMainRenderer().getDbg().setDitheredDepthTestEnabled(false);
  148. }
  149. else
  150. {
  151. getMainRenderer().getDbg().setEnabled(true);
  152. getMainRenderer().getDbg().setDepthTestEnabled(false);
  153. getMainRenderer().getDbg().setDitheredDepthTestEnabled(true);
  154. }
  155. }
  156. if(getInput().getKey(KeyCode::R))
  157. {
  158. SceneNode& player = getSceneGraph().findSceneNode("player");
  159. player.getComponent<PlayerControllerComponent>().moveToPosition(Vec4(0.0f, 2.0f, 0.0f, 0.0f));
  160. }
  161. if(getInput().getMouseButton(MouseButton::LEFT) == 1)
  162. {
  163. ANKI_LOGI("Firing a monkey");
  164. static U instance = 0;
  165. Transform camTrf = getSceneGraph().getActiveCameraNode().getComponent<MoveComponent>().getWorldTransform();
  166. ModelNode* monkey;
  167. ANKI_CHECK(getSceneGraph().newSceneNode<ModelNode>(
  168. StringAuto(getAllocator()).sprintf("monkey%u", instance++).toCString(),
  169. monkey,
  170. "assets/Suzannedynamic-material.ankimdl"));
  171. // monkey->getComponent<MoveComponent>().setLocalTransform(camTrf);
  172. BodyNode* body;
  173. ANKI_CHECK(getSceneGraph().newSceneNode<BodyNode>(
  174. StringAuto(getAllocator()).sprintf("bmonkey%u", instance++).toCString(), body, "assets/Suzanne.ankicl"));
  175. body->getComponent<BodyComponent>().setTransform(camTrf);
  176. PhysicsBodyPtr pbody = body->getComponent<BodyComponent>().getPhysicsBody();
  177. pbody->applyForce(camTrf.getRotation().getZAxis().xyz() * -1500.0f, Vec3(0.0f, 0.0f, 0.0f));
  178. body->addChild(monkey);
  179. // Create the destruction event
  180. createDestructionEvent(body);
  181. }
  182. if(getInput().getMouseButton(MouseButton::RIGHT) == 1)
  183. {
  184. Transform camTrf = getSceneGraph().getActiveCameraNode().getComponent<MoveComponent>().getWorldTransform();
  185. Vec3 from = camTrf.getOrigin().xyz();
  186. Vec3 to = from + -camTrf.getRotation().getZAxis() * 100.0f;
  187. RayCast ray(from, to, PhysicsMaterialBit::ALL & (~PhysicsMaterialBit::PARTICLE));
  188. ray.m_firstHit = true;
  189. getPhysicsWorld().rayCast(ray);
  190. if(ray.m_hit)
  191. {
  192. // Create rotation
  193. const Vec3& zAxis = ray.m_hitNormal;
  194. Vec3 yAxis = Vec3(0, 1, 0.5);
  195. Vec3 xAxis = yAxis.cross(zAxis).getNormalized();
  196. yAxis = zAxis.cross(xAxis);
  197. Mat3x4 rot = Mat3x4::getIdentity();
  198. rot.setXAxis(xAxis);
  199. rot.setYAxis(yAxis);
  200. rot.setZAxis(zAxis);
  201. Transform trf(ray.m_hitPosition.xyz0(), rot, 1.0f);
  202. // Create an obj
  203. static U id = 0;
  204. ModelNode* monkey;
  205. ANKI_CHECK(getSceneGraph().newSceneNode(
  206. StringAuto(getSceneGraph().getFrameAllocator()).sprintf("decal%u", id++).toCString(),
  207. monkey,
  208. "assets/Suzannedynamic-material.ankimdl"));
  209. monkey->getComponent<MoveComponent>().setLocalTransform(trf);
  210. createDestructionEvent(monkey);
  211. #if 0
  212. // Create some particles
  213. ParticleEmitterNode* particles;
  214. ANKI_CHECK(getSceneGraph().newSceneNode(
  215. StringAuto(getSceneGraph().getFrameAllocator()).sprintf("parts%u", id++).toCString(),
  216. particles,
  217. "assets/smoke.ankipart"));
  218. particles->getComponent<MoveComponent>().setLocalTransform(trf);
  219. createDestructionEvent(particles);
  220. #endif
  221. // Create some fog volumes
  222. for(U i = 0; i < 1; ++i)
  223. {
  224. static int id = 0;
  225. StringAuto name(getSceneGraph().getFrameAllocator());
  226. name.sprintf("fog%u", id++);
  227. FogDensityNode* fogNode;
  228. ANKI_CHECK(getSceneGraph().newSceneNode(name.toCString(), fogNode));
  229. FogDensityComponent& fogComp = fogNode->getComponent<FogDensityComponent>();
  230. fogComp.setSphere(2.1f);
  231. fogComp.setDensity(15.0f);
  232. BodyNode* body;
  233. name.sprintf("fogbody%u", id++);
  234. ANKI_CHECK(getSceneGraph().newSceneNode(name.toCString(), body, "assets/sphere_r2.ankicl"));
  235. body->getComponent<BodyComponent>().setTransform(trf);
  236. body->addChild(fogNode);
  237. }
  238. }
  239. }
  240. if(0)
  241. {
  242. SceneNode& node = getSceneGraph().findSceneNode("trigger");
  243. TriggerComponent& comp = node.getComponent<TriggerComponent>();
  244. for(U i = 0; i < comp.getContactSceneNodes().getSize(); ++i)
  245. {
  246. ANKI_LOGI("Touching %s", comp.getContactSceneNodes()[i]->getName().cstr());
  247. }
  248. }
  249. return Error::NONE;
  250. }
  251. int main(int argc, char* argv[])
  252. {
  253. Error err = Error::NONE;
  254. MyApp* app = new MyApp;
  255. err = app->init(argc, argv, argv[0]);
  256. if(!err)
  257. {
  258. err = app->mainLoop();
  259. }
  260. if(err)
  261. {
  262. ANKI_LOGE("Error reported. Bye!");
  263. }
  264. else
  265. {
  266. delete app;
  267. ANKI_LOGI("Bye!!");
  268. }
  269. return 0;
  270. }