Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stdafx.h"
- #include "Pillars.h"
- #include "Core\HField.h"
- // You must furnish your own Maker and Killer functions. The Maker should (obviously) be unique for each device,
- // while the Killer can be shared among plugins in the same DLL. The basic idea is to get around the sometimes-messy
- // problem of DLL<->Client heap management. The framework will call your maker and killers as appropriate.
- Device *PillarsMaker() { return new Pillars; };
- void PillarsKiller(Device *spr) { delete spr; };
- // What you MUST DO in the constructor of your device:
- // 1) Set the Nametag, Maker and Killer in the lifeptrs struct.
- // What you SHOULD do in the constructor:
- // 2) Call SetLinks() with the # of inputs and outputs your device is going to use
- // ...if you dont do #2, you will use the default # of inputs your parent class assigns
- Pillars::Pillars(void)
- {
- lifeptrs.maker = PillarsMaker;
- lifeptrs.killer = PillarsKiller;
- strncpy(lifeptrs.nametag, "EXIV", 4);
- SetLinks(2, 1);
- // This is how you would add a parameter to a device that is managed by the generic dlg system
- // This adds a floating point parameter. You can add floats, ints, bools, or enums.
- AddParam(Parameter("Dummy Parameter", 0.0f, 0.0f, 1.0f));
- }
- // This is a convenient way to access your device parameters
- // Note that accessing parameters is really quite slow due to the string searching for the param name.
- // Do NOT call inside of loops if you care about performance -- just retrieve the value once and cache it.
- #define INV_DUMMY ParmFRef("Dummy Parameter")
- Pillars::~Pillars(void)
- {
- }
- // 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
- // have an internal version number that you keep track of to allow backwards-compatibility if you ever change your Device save layout...
- // Also, make sure you call your super class's Load and Save functions as shown here. Failure to do so will cause major problems.
- bool Pillars::Load(std::istream &in) {
- char tag[5];
- in.read( tag, 4);
- if (strncmp(tag, lifeptrs.nametag, 4) == 0) {
- int ver = 0;
- in.read((char*) &ver, 1);
- return Filter::Load(in);
- }
- else
- return false;
- };
- bool Pillars::Save(std::ostream &out) {
- out.write( lifeptrs.nametag, 4);
- int ver = 1;
- out.write((char*) &ver, 1);
- return Filter::Save(out);
- };
- // The Activate function is where you work your magic. You should do four things in the Activate function:
- // 1) Retrieve your inputs by calling RetrieveData(input#)
- // 2) Do whatever you will do on it...
- // 3) Store the data to make it available to your outputs
- // 4) Return true to indicate successful activation, or false if there was an error.
- bool Pillars::Activate(BuildContext &context) {
- HFPointer hf = HF(RetrieveInput(1, context) ); // Use the RetrieveData(),StoreData() pair to get and set your heightfields
- HFPointer hf2 = HF(RetrieveInput(0, context) ); // Use the RetrieveData(),StoreData() pair to get and set your heightfields
- HFPointer hf3 = HF(RetrieveInput(0, context) ); // WOOHOO FREE HEIGHTFIELD!
- // 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
- if (!hf)
- return false;
- if (!hf2)
- return false;
- if (!hf3)
- return false;
- // ** example: if we actually DID anything with our dummy param, this is how you would get it
- float dummy = INV_DUMMY;
- // ** example: If you wanted to access the data by coordinate instead of by index, here's how you would do it:
- int width = hf->w();
- int height = hf->h();
- float dummy_height = (*hf)[Coord(0,0)]; // use the coordinate version of the hf array operator
- size_t area = hf->area(); // use size_t for heightfield iterating as it is possible for the index to exceed 32bits..
- // 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:
- float curr=-1;
- bool panic=false;
- for (size_t i=0; i<width; i++){
- for (size_t j=0; j<height;j++){
- size_t pos=j*height+i;
- if((*hf)[pos]<0){
- continue;
- }else{
- curr=(*hf)[pos];
- int avgx=i;
- int avgy=j;
- size_t pcnt=1;
- walk(curr, i,j,height,width,&avgx,&avgy,&pcnt,hf,hf2,hf3,-1,0);
- int phx=int(avgx/pcnt);
- int phy=int(avgy/pcnt);
- if (phx<0 || phx>=width || phy<0 || phy>= height){panic=true; break;};
- float pillarheight=(*hf2)[ phx+ height*phy];
- walk(curr, i,j,height,width,&avgx,&avgy,&pcnt,hf,hf2,hf3, pillarheight,0);
- }
- }
- if (panic) break;
- }
- // Handoff to output(s)
- //hf->ClampRange();
- //StoreData(hf,0, context); // pass the heightfield to our output stage.
- hf2->ClampRange();
- StoreData(hf2,0, context); // pass the heightfield to our output stage.
- // hf3->ClampRange();
- //StoreData(hf3,2, context); // pass the heightfield to our output stage.
- // Success!
- return true;
- }
- 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){
- depth++;
- if (pheight<0){
- if ((*hf)[x +y*height] ==curr && ((*hf3)[x +y*height]>=0)){
- (*hf3)[x +y*height]-=2.0;
- *avgx+=x;
- *avgy+=y;
- *pcnt+=1;
- 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.
- if (x+1< width) walk(curr,min(x+1,width-1) ,y,height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth);
- if (y+1<height) walk(curr,x,min(y+1,height-1),height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth);
- //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!
- if (y>0) walk(curr,x,max(0,y-1),height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth);
- }
- }
- else{
- if ((*hf)[x +y*height] ==curr && (*hf3)[x +y*height] <-1.0 && (*hf3)[x +y*height] >=-4.0){
- (*hf3)[x +y*height]-=10.0;
- if (depth>2000) return;
- if (x+1< width) walk(curr,min(x+1,width-1) ,y,height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth);
- if (y+1<height) walk(curr,x,min(y+1,height-1),height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth);
- //if (x>0) walk(curr,x-1,y,height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth); //
- if (y>0) walk(curr,x,max(0,y-1),height, width, avgx,avgy,pcnt,hf,hf2,hf3,pheight,depth);
- (*hf2)[x +y*height]=pheight;
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement