Advertisement
Guest User

Pillars.cpp

a guest
May 14th, 2013
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.48 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "Pillars.h"
  3. #include "Core\HField.h"
  4.  
  5. // You must furnish your own Maker and Killer functions. The Maker should (obviously) be unique for each device,
  6. // while the Killer can be shared among plugins in the same DLL. The basic idea is to get around the sometimes-messy
  7. // problem of DLL<->Client heap management. The framework will call your maker and killers as appropriate.
  8.  
  9. Device *PillarsMaker() { return new Pillars; };
  10. void PillarsKiller(Device *spr) { delete spr; };
  11.  
  12. // What you MUST DO in the constructor of your device:
  13. // 1) Set the Nametag, Maker and Killer in the lifeptrs struct.
  14. // What you SHOULD do in the constructor:
  15. // 2) Call SetLinks() with the # of inputs and outputs your device is going to use
  16. // ...if you dont do #2, you will use the default # of inputs your parent class assigns
  17. Pillars::Pillars(void)
  18. {
  19. lifeptrs.maker = PillarsMaker;
  20. lifeptrs.killer = PillarsKiller;
  21. strncpy(lifeptrs.nametag, "EXIV", 4);
  22. SetLinks(2, 1);
  23. // This is how you would add a parameter to a device that is managed by the generic dlg system
  24. // This adds a floating point parameter. You can add floats, ints, bools, or enums.
  25. AddParam(Parameter("Dummy Parameter", 0.0f, 0.0f, 1.0f));
  26. }
  27.  
  28. // This is a convenient way to access your device parameters
  29. // Note that accessing parameters is really quite slow due to the string searching for the param name.
  30. // Do NOT call inside of loops if you care about performance -- just retrieve the value once and cache it.
  31. #define INV_DUMMY ParmFRef("Dummy Parameter")
  32.  
  33.  
  34. Pillars::~Pillars(void)
  35. {
  36.  
  37. }
  38.  
  39. // You are REQUIRED to write out and read in your 4-byte Device ID tag, as shown below. It is also recommended that your device
  40. // have an internal version number that you keep track of to allow backwards-compatibility if you ever change your Device save layout...
  41. // Also, make sure you call your super class's Load and Save functions as shown here. Failure to do so will cause major problems.
  42. bool Pillars::Load(std::istream &in) {
  43. char tag[5];
  44. in.read( tag, 4);
  45. if (strncmp(tag, lifeptrs.nametag, 4) == 0) {
  46. int ver = 0;
  47. in.read((char*) &ver, 1);
  48. return Filter::Load(in);
  49. }
  50. else
  51. return false;
  52. };
  53.  
  54. bool Pillars::Save(std::ostream &out) {
  55. out.write( lifeptrs.nametag, 4);
  56. int ver = 1;
  57. out.write((char*) &ver, 1);
  58. return Filter::Save(out);
  59. };
  60.  
  61. // The Activate function is where you work your magic. You should do four things in the Activate function:
  62. // 1) Retrieve your inputs by calling RetrieveData(input#)
  63. // 2) Do whatever you will do on it...
  64. // 3) Store the data to make it available to your outputs
  65. // 4) Return true to indicate successful activation, or false if there was an error.
  66. bool Pillars::Activate(BuildContext &context) {
  67. HFPointer hf = HF(RetrieveInput(1, context) ); // Use the RetrieveData(),StoreData() pair to get and set your heightfields
  68. HFPointer hf2 = HF(RetrieveInput(0, context) ); // Use the RetrieveData(),StoreData() pair to get and set your heightfields
  69. HFPointer hf3 = HF(RetrieveInput(0, context) ); // WOOHOO FREE HEIGHTFIELD!
  70.  
  71. // This is important! An input CAN RETURN NULL if it is not connected, or the input is turned off. So always check and bail out if its not there
  72. if (!hf)
  73. return false;
  74. if (!hf2)
  75. return false;
  76. if (!hf3)
  77. return false;
  78.  
  79. // ** example: if we actually DID anything with our dummy param, this is how you would get it
  80. float dummy = INV_DUMMY;
  81.  
  82. // ** example: If you wanted to access the data by coordinate instead of by index, here's how you would do it:
  83. int width = hf->w();
  84. int height = hf->h();
  85. float dummy_height = (*hf)[Coord(0,0)]; // use the coordinate version of the hf array operator
  86. size_t area = hf->area(); // use size_t for heightfield iterating as it is possible for the index to exceed 32bits..
  87.  
  88. // heights are always in the range 0..1., it also doesn't care about world space location, so we can just do a simple iteration over the entire data field:
  89.  
  90. float curr=-1;
  91. bool panic=false;
  92. for (size_t i=0; i<width; i++){
  93. for (size_t j=0; j<height;j++){
  94. size_t pos=j*height+i;
  95.  
  96. if((*hf)[pos]<0){
  97. continue;
  98. }else{
  99. curr=(*hf)[pos];
  100. int avgx=i;
  101. int avgy=j;
  102. size_t pcnt=1;
  103. walk(curr, i,j,height,width,&avgx,&avgy,&pcnt,hf,hf2,hf3,-1,0);
  104. int phx=int(avgx/pcnt);
  105. int phy=int(avgy/pcnt);
  106. if (phx<0 || phx>=width || phy<0 || phy>= height){panic=true; break;};
  107. float pillarheight=(*hf2)[ phx+ height*phy];
  108.  
  109. walk(curr, i,j,height,width,&avgx,&avgy,&pcnt,hf,hf2,hf3, pillarheight,0);
  110. }
  111. }
  112. if (panic) break;
  113. }
  114.  
  115. // Handoff to output(s)
  116. //hf->ClampRange();
  117. //StoreData(hf,0, context); // pass the heightfield to our output stage.
  118. hf2->ClampRange();
  119. StoreData(hf2,0, context); // pass the heightfield to our output stage.
  120. // hf3->ClampRange();
  121. //StoreData(hf3,2, context); // pass the heightfield to our output stage.
  122. // Success!
  123. return true;
  124. }
  125. void Pillars::walk(float curr,int x, int y, int height, int width, int * avgx, int * avgy, size_t* pcnt, HFPointer hf, HFPointer hf2, HFPointer hf3, float pheight,int depth){
  126. depth++;
  127.  
  128. if (pheight<0){
  129. if ((*hf)[x +y*height] ==curr && ((*hf3)[x +y*height]>=0)){
  130. (*hf3)[x +y*height]-=2.0;
  131.  
  132. *avgx+=x;
  133. *avgy+=y;
  134. *pcnt+=1;
  135. if (depth>2500) return; //MSVC2010 default max stack depth is 256kb, and with 56 bytes of stuff on the stack per call, this maxes at about 4500 calls. 2500 is a sensible max.
  136. if (x+1< width) walk(curr,min(x+1,width-1) ,y,height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth);
  137. if (y+1<height) walk(curr,x,min(y+1,height-1),height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth);
  138. //if (x>0) walk(curr,x-1,y,height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth); //THERE IS NO TURNING BACK! We assume (hopefully) that all voronoi shapes are CONVEX!
  139. if (y>0) walk(curr,x,max(0,y-1),height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth);
  140. }
  141. }
  142. else{
  143. if ((*hf)[x +y*height] ==curr && (*hf3)[x +y*height] <-1.0 && (*hf3)[x +y*height] >=-4.0){
  144. (*hf3)[x +y*height]-=10.0;
  145. if (depth>2000) return;
  146. if (x+1< width) walk(curr,min(x+1,width-1) ,y,height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth);
  147. if (y+1<height) walk(curr,x,min(y+1,height-1),height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth);
  148. //if (x>0) walk(curr,x-1,y,height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth); //
  149. if (y>0) walk(curr,x,max(0,y-1),height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth);
  150. (*hf2)[x +y*height]=pheight;
  151. }
  152. }
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement