guiTerrPreviewCtrl.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "console/console.h"
  23. #include "console/consoleTypes.h"
  24. #include "terrain/terrData.h"
  25. #include "gui/worldEditor/guiTerrPreviewCtrl.h"
  26. #include "gfx/primBuilder.h"
  27. #include "T3D/gameFunctions.h"
  28. IMPLEMENT_CONOBJECT(GuiTerrPreviewCtrl);
  29. ConsoleDocClass( GuiTerrPreviewCtrl,
  30. "@brief Very old GUI used for terrain preview\n\n"
  31. "Deprecated\n\n"
  32. "@internal"
  33. );
  34. GuiTerrPreviewCtrl::GuiTerrPreviewCtrl(void) : mTerrainEditor(NULL), mTerrainSize(2048.0f)
  35. {
  36. mRoot.set( 0, 0 );
  37. mOrigin.set( 0, 0 );
  38. mWorldScreenCenter.set( mTerrainSize*0.5f, mTerrainSize*0.5f );
  39. mControlsStateBlock = NULL;
  40. mTerrainBitmapStateBlock = NULL;
  41. }
  42. bool GuiTerrPreviewCtrl::onAdd()
  43. {
  44. if(Parent::onAdd() == false)
  45. {
  46. return false;
  47. }
  48. SimObject* inTerrEditor = Sim::findObject("ETerrainEditor");
  49. if(!inTerrEditor)
  50. {
  51. Con::errorf(ConsoleLogEntry::General, "TerrainEditor::onAdd: failed to load Terrain Editor");
  52. return false;
  53. }
  54. mTerrainEditor = dynamic_cast<TerrainEditor*>(inTerrEditor);
  55. GFXStateBlockDesc desc;
  56. desc.setBlend(false, GFXBlendOne, GFXBlendZero);
  57. desc.samplersDefined = true;
  58. desc.samplers[0].addressModeU = GFXAddressWrap;
  59. desc.samplers[0].addressModeV = GFXAddressWrap;
  60. desc.samplers[0].textureColorOp = GFXTOPSelectARG1;
  61. desc.samplers[0].colorArg1 = GFXTATexture;
  62. desc.setCullMode(GFXCullNone);
  63. desc.setZReadWrite(false);
  64. mTerrainBitmapStateBlock = GFX->createStateBlock(desc);
  65. desc.samplers[0].textureColorOp = GFXTOPDisable;
  66. mControlsStateBlock = GFX->createStateBlock(desc);
  67. return true;
  68. }
  69. void GuiTerrPreviewCtrl::initPersistFields()
  70. {
  71. Parent::initPersistFields();
  72. }
  73. ConsoleMethod( GuiTerrPreviewCtrl, reset, void, 2, 2, "Reset the view of the terrain.")
  74. {
  75. object->reset();
  76. }
  77. ConsoleMethod( GuiTerrPreviewCtrl, setRoot, void, 2, 2, "Add the origin to the root and reset the origin.")
  78. {
  79. object->setRoot();
  80. }
  81. ConsoleMethod( GuiTerrPreviewCtrl, getRoot, const char *, 2, 2, "Return a Point2F representing the position of the root.")
  82. {
  83. Point2F p = object->getRoot();
  84. static char rootbuf[32];
  85. dSprintf(rootbuf,sizeof(rootbuf),"%g %g", p.x, -p.y);
  86. return rootbuf;
  87. }
  88. ConsoleMethod( GuiTerrPreviewCtrl, setOrigin, void, 4, 4, "(float x, float y)"
  89. "Set the origin of the view.")
  90. {
  91. object->setOrigin( Point2F( dAtof(argv[2]), -dAtof(argv[3]) ) );
  92. }
  93. ConsoleMethod( GuiTerrPreviewCtrl, getOrigin, const char*, 2, 2, "Return a Point2F containing the position of the origin.")
  94. {
  95. Point2F p = object->getOrigin();
  96. static char originbuf[32];
  97. dSprintf(originbuf,sizeof(originbuf),"%g %g", p.x, -p.y);
  98. return originbuf;
  99. }
  100. ConsoleMethod( GuiTerrPreviewCtrl, getValue, const char*, 2, 2, "Returns a 4-tuple containing: root_x root_y origin_x origin_y")
  101. {
  102. Point2F r = object->getRoot();
  103. Point2F o = object->getOrigin();
  104. static char valuebuf[64];
  105. dSprintf(valuebuf,sizeof(valuebuf),"%g %g %g %g", r.x, -r.y, o.x, -o.y);
  106. return valuebuf;
  107. }
  108. ConsoleMethod( GuiTerrPreviewCtrl, setValue, void, 3, 3, "Accepts a 4-tuple in the same form as getValue returns.\n\n"
  109. "@see GuiTerrPreviewCtrl::getValue()")
  110. {
  111. Point2F r,o;
  112. dSscanf(argv[2],"%g %g %g %g", &r.x, &r.y, &o.x, &o.y);
  113. r.y = -r.y;
  114. o.y = -o.y;
  115. object->reset();
  116. object->setRoot(r);
  117. object->setOrigin(o);
  118. }
  119. bool GuiTerrPreviewCtrl::onWake()
  120. {
  121. if (! Parent::onWake())
  122. return false;
  123. return true;
  124. }
  125. void GuiTerrPreviewCtrl::onSleep()
  126. {
  127. Parent::onSleep();
  128. }
  129. void GuiTerrPreviewCtrl::setBitmap(const GFXTexHandle &handle)
  130. {
  131. mTextureHandle = handle;
  132. }
  133. void GuiTerrPreviewCtrl::reset()
  134. {
  135. mRoot.set(0,0);
  136. mOrigin.set(0,0);
  137. }
  138. void GuiTerrPreviewCtrl::setRoot()
  139. {
  140. mRoot += mOrigin;
  141. mOrigin.set(0,0);
  142. }
  143. void GuiTerrPreviewCtrl::setRoot(const Point2F &p)
  144. {
  145. mRoot = p;
  146. }
  147. void GuiTerrPreviewCtrl::setOrigin(const Point2F &p)
  148. {
  149. mOrigin = p;
  150. }
  151. Point2F& GuiTerrPreviewCtrl::wrap(const Point2F &p)
  152. {
  153. static Point2F result;
  154. result = p;
  155. while (result.x < 0.0f)
  156. result.x += mTerrainSize;
  157. while (result.x > mTerrainSize)
  158. result.x -= mTerrainSize;
  159. while (result.y < 0.0f)
  160. result.y += mTerrainSize;
  161. while (result.y > mTerrainSize)
  162. result.y -= mTerrainSize;
  163. return result;
  164. }
  165. Point2F& GuiTerrPreviewCtrl::worldToTexture(const Point2F &p)
  166. {
  167. static Point2F result;
  168. result = wrap( p + mRoot ) / mTerrainSize;
  169. return result;
  170. }
  171. Point2F& GuiTerrPreviewCtrl::worldToCtrl(const Point2F &p)
  172. {
  173. static Point2F result;
  174. result = wrap( p - mCamera - mWorldScreenCenter );
  175. result *= getWidth() / mTerrainSize;
  176. return result;
  177. }
  178. void GuiTerrPreviewCtrl::onPreRender()
  179. {
  180. setUpdate();
  181. }
  182. void GuiTerrPreviewCtrl::onRender(Point2I offset, const RectI &updateRect)
  183. {
  184. CameraQuery query;
  185. GameProcessCameraQuery(&query);
  186. Point3F cameraRot;
  187. TerrainBlock *terrBlock = NULL;
  188. MatrixF matrix = query.cameraMatrix;
  189. matrix.getColumn(3,&cameraRot); // get Camera translation
  190. mCamera.set(cameraRot.x, -cameraRot.y);
  191. matrix.getRow(1,&cameraRot); // get camera rotation
  192. if (mTerrainEditor != NULL)
  193. terrBlock = mTerrainEditor->getActiveTerrain();
  194. if (!terrBlock)
  195. return;
  196. for(U32 i = 0; i < GFX->getNumSamplers(); i++)
  197. GFX->setTexture(i, NULL);
  198. GFX->setupGenericShaders(GFXDevice::GSModColorTexture);
  199. Point2F terrPos(terrBlock->getPosition().x, terrBlock->getPosition().y);
  200. mTerrainSize = terrBlock->getWorldBlockSize();
  201. //----------------------------------------- RENDER the Terrain Bitmap
  202. if (mTextureHandle)
  203. {
  204. GFXTextureObject *texture = (GFXTextureObject*)mTextureHandle;
  205. if (texture)
  206. {
  207. //GFX->setLightingEnable(false);
  208. GFX->setStateBlock(mTerrainBitmapStateBlock);
  209. GFX->setTexture(0, texture);
  210. Point2F screenP1(offset.x - 0.5f, offset.y + 0.5f);
  211. Point2F screenP2(offset.x + getWidth() - 0.5f, offset.y + getWidth() + 0.5f);
  212. Point2F textureP1( worldToTexture( mCamera - terrPos ) - Point2F(0.5f, 0.5f));
  213. Point2F textureP2(textureP1 + Point2F(1.0f, 1.0f));
  214. // the texture if flipped horz to reflect how the terrain is really drawn
  215. PrimBuild::color3f(1.0f, 1.0f, 1.0f);
  216. PrimBuild::begin(GFXTriangleFan, 4);
  217. PrimBuild::texCoord2f(textureP1.x, textureP2.y);
  218. PrimBuild::vertex2f(screenP1.x, screenP2.y); // left bottom
  219. PrimBuild::texCoord2f(textureP2.x, textureP2.y);
  220. PrimBuild::vertex2f(screenP2.x, screenP2.y); // right bottom
  221. PrimBuild::texCoord2f(textureP2.x, textureP1.y);
  222. PrimBuild::vertex2f(screenP2.x, screenP1.y); // right top
  223. PrimBuild::texCoord2f(textureP1.x, textureP1.y);
  224. PrimBuild::vertex2f(screenP1.x, screenP1.y); // left top
  225. PrimBuild::end();
  226. }
  227. }
  228. //Draw blank texture
  229. else
  230. {
  231. RectI rect(offset.x, offset.y, getWidth(), getHeight());
  232. GFX->getDrawUtil()->drawRect(rect, ColorI(0,0,0));
  233. }
  234. GFX->setStateBlock(mControlsStateBlock);
  235. //----------------------------------------- RENDER the '+' at the center of the Block
  236. PrimBuild::color4f(1.0f, 1.0f, 1.0f, 1.0f);
  237. Point2F center( worldToCtrl(terrPos + Point2F(mTerrainSize * 0.5f, mTerrainSize * 0.5f)) );
  238. S32 y;
  239. for (y=-1; y<=1; y++)
  240. {
  241. F32 yoffset = offset.y + y*256.0f;
  242. for (S32 x=-1; x<=1; x++)
  243. {
  244. F32 xoffset = offset.x + x*256.0f;
  245. PrimBuild::begin(GFXLineList, 4);
  246. PrimBuild::vertex2f(xoffset + center.x, yoffset + center.y-5);
  247. PrimBuild::vertex2f(xoffset + center.x, yoffset + center.y+6);
  248. PrimBuild::vertex2f(xoffset + center.x-5, yoffset + center.y);
  249. PrimBuild::vertex2f(xoffset + center.x+6, yoffset + center.y);
  250. PrimBuild::end();
  251. }
  252. }
  253. //----------------------------------------- RENDER the Block Corners
  254. Point2F cornerf( worldToCtrl(terrPos) + Point2F(0.125f, 0.125f));
  255. Point2I corner=Point2I((S32)cornerf.x,(S32)cornerf.y);
  256. for (y=-1; y<=1; y++)
  257. {
  258. S32 yoffset = offset.y + y*256;
  259. for (S32 x=-1; x<=1; x++)
  260. {
  261. S32 xoffset = offset.x + x*256;
  262. PrimBuild::begin(GFXLineStrip, 3);
  263. PrimBuild::color4f(1.0f, 1.0f, 1.0f, 0.3f);
  264. PrimBuild::vertex2i(xoffset + corner.x, yoffset + corner.y-128);
  265. PrimBuild::color4f(1.0f, 1.0f, 1.0f, 0.7f);
  266. PrimBuild::vertex2i(xoffset + corner.x, yoffset + corner.y);
  267. PrimBuild::color4f(1.0f, 1.0f, 1.0f, 0.3f);
  268. PrimBuild::vertex2i(xoffset + corner.x+128, yoffset + corner.y);
  269. PrimBuild::end();
  270. PrimBuild::begin(GFXLineStrip, 3);
  271. PrimBuild::color4f(1.0f, 1.0f, 1.0f, 0.3f);
  272. PrimBuild::vertex2i(xoffset + corner.x, yoffset + corner.y+128);
  273. PrimBuild::color4f(1.0f, 1.0f, 1.0f, 0.7f);
  274. PrimBuild::vertex2i(xoffset + corner.x, yoffset + corner.y);
  275. PrimBuild::color4f(1.0f, 1.0f, 1.0f, 0.3f);
  276. PrimBuild::vertex2i(xoffset + corner.x-128, yoffset + corner.y);
  277. PrimBuild::end();
  278. }
  279. }
  280. //----------------------------------------- RENDER the Viewcone
  281. Point2F pointA(cameraRot.x * -40, cameraRot.y * -40);
  282. Point2F pointB(-pointA.y, pointA.x);
  283. F32 tann = mTan(0.5f);
  284. Point2F point1( pointA + pointB * tann );
  285. Point2F point2( pointA - pointB * tann );
  286. center.set((F32)(offset.x + getWidth() / 2), (F32)(offset.y + getHeight() / 2 ));
  287. PrimBuild::begin(GFXLineStrip, 3);
  288. PrimBuild::color4f(1.0f, 0.0f, 0.0f, 0.7f);
  289. PrimBuild::vertex2i((S32)(center.x + point1.x), (S32)(center.y + point1.y));
  290. PrimBuild::color4f(1.0f, 0.0f, 0.0f, 1.0f);
  291. PrimBuild::vertex2i((S32)center.x,(S32)center.y);
  292. PrimBuild::color4f(1.0f, 0.0f, 0.0f, 0.7f);
  293. PrimBuild::vertex2i((S32)(center.x + point2.x), (S32)(center.y + point2.y));
  294. PrimBuild::end();
  295. renderChildControls(offset, updateRect);
  296. }