mapLoader.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. ########################################################################
  2. # Hello Worlds - Libre 3D RPG game.
  3. # Copyright (C) 2020 CYBERDEViL
  4. #
  5. # This file is part of Hello Worlds.
  6. #
  7. # Hello Worlds is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # Hello Worlds is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  19. #
  20. ########################################################################
  21. from panda3d.core import AmbientLight, DirectionalLight
  22. from panda3d.core import Fog
  23. from panda3d.core import Vec3
  24. from panda3d.bullet import BulletTriangleMesh
  25. from panda3d.bullet import BulletTriangleMeshShape
  26. from panda3d.bullet import BulletRigidBodyNode
  27. from core.db import Maps
  28. from direct.showbase import DirectObject
  29. class MapLoader(DirectObject.DirectObject):
  30. def __init__(self, world, worldNP):
  31. """ Map values
  32. - file
  33. - background color
  34. - fog
  35. - lightning
  36. """
  37. self._world = world
  38. self._world.setGravity(Vec3(0, 0, -9.81))
  39. self._worldNP = worldNP
  40. self._currentId = -1;
  41. self._loadingId = -1;
  42. self._map = None
  43. self._fog = None
  44. self._np = None
  45. self._finisehdLoadingCallback = None
  46. # TODO create list/dict for lights with options to set per map
  47. self._ambientLight = None
  48. self._directionalLight = None
  49. @property
  50. def currentId(self):
  51. return self._currentId
  52. @property
  53. def currentMap(self):
  54. return Maps[self.currentId]
  55. def unload(self):
  56. if not self._map:
  57. print("Tried to unload a map, but no loaded.");
  58. return
  59. loader.unloadModel(self._map)
  60. self._map.removeNode()
  61. del self._map
  62. self._map = None
  63. self._world.remove(self._np.node())
  64. self._np.removeNode()
  65. self._np = None
  66. if self._fog:
  67. #self._fog.detachNode()
  68. #self._fog.removeNode()
  69. self._fog = None
  70. render.clearFog()
  71. if self._ambientLight:
  72. #self._ambientLight.detachNode()
  73. #self._ambientLight.removeNode()
  74. self._ambientLight = None
  75. if self._directionalLight:
  76. #self._directionalLight.detachNode()
  77. #self._directionalLight.removeNode()
  78. self._directionalLight = None
  79. render.clearLight()
  80. self._currentId = -1;
  81. def _finisehdLoading(self, loadedMap):
  82. print("_finisehdLoading")
  83. self._map = loadedMap
  84. # Create a new node point for our Enviroment.
  85. self._np = self._worldNP.attachNewNode(BulletRigidBodyNode('Enviroment'))
  86. # Go over all objects in the PandaNode loaded from a file.
  87. for match in self._map.findAllMatches('**/+GeomNode'):
  88. # If in blender under game properties a property with the name
  89. # `m_collide` is set and is a True value then add a collision
  90. # mesh.
  91. if match.node().getTag('m_collide'):
  92. mesh = BulletTriangleMesh()
  93. mesh.addGeom(match.node().getGeom(0))
  94. shape = BulletTriangleMeshShape(mesh, dynamic=False)
  95. t = match.node().getTransform()
  96. self._np.node().addShape(shape, t)
  97. match.clearModelNodes()
  98. match.reparentTo(self._np)
  99. self._world.attach(self._np.node())
  100. # TODO Setup per map.
  101. # Fog
  102. self._fog = Fog('mapFog')
  103. fogColor = (0.25, 0.25, 0.25)
  104. # 0.3, 0.3, 0.4, 1
  105. self._fog.setColor(*fogColor)
  106. #self._fog.setExpDensity(.015)
  107. self._fog.setExpDensity(.01)
  108. #self._fog.setColor(*fogColor)
  109. #self._fog.setLinearRange(0,320)
  110. #self._fog.setLinearFallback(45,160,320)
  111. #base.setBackgroundColor(*fogColor)
  112. render.setFog(self._fog)
  113. # Create some lighting
  114. self._ambientLight = AmbientLight("ambientLight")
  115. self._ambientLight.setColor((.3, .3, .3, 1))
  116. self._directionalLight = DirectionalLight("directionalLight")
  117. self._directionalLight.setDirection((-5, -5, -5))
  118. self._directionalLight.setColor((1, 1, 1, 1))
  119. self._directionalLight.setSpecularColor((1, 1, 1, 1))
  120. render.setLight(render.attachNewNode(self._ambientLight))
  121. render.setLight(render.attachNewNode(self._directionalLight))
  122. # Additional lights
  123. self._directionalLight2 = DirectionalLight("directionalLight")
  124. self._directionalLight2.setDirection((-200, 400, -25))
  125. self._directionalLight2.setColor((1, 1, 1, 1))
  126. self._directionalLight2.setSpecularColor((1, 1, 1, 1))
  127. render.setLight(render.attachNewNode(self._directionalLight2))
  128. self._currentId = self._loadingId
  129. self._loadingId = -1
  130. if self._finisehdLoadingCallback:
  131. self._finisehdLoadingCallback()
  132. self._finisehdLoadingCallback = None
  133. def load(self, id, callback=None):
  134. if self._currentId != -1:
  135. print("Already a map loaded, please unload that first.");
  136. return
  137. map = Maps[id]
  138. if not map:
  139. print("Map with id: `{0}` not found.".format(id));
  140. return
  141. self._finisehdLoadingCallback = callback
  142. self._loadingId = id
  143. # Load file into PandaNode.
  144. loader.loadModel(
  145. map.filePath,
  146. callback = self._finisehdLoading,
  147. );