develop
Japa 2013-06-28 17:39:49 +05:30
commit 196e3a3017
4 changed files with 122 additions and 43 deletions

@ -222,7 +222,7 @@ void plotSquare(int xm, int ym, int r,std::function<void(int,int)> setPixel)
setPixel(xm-x, ym+r); /* IV.2 Quadrant */ setPixel(xm-x, ym+r); /* IV.2 Quadrant */
} }
} }
void plotLine(int x0, int y0, int x1, int y1,std::function<bool(int,int,int,int)> setPixel) void plotLine(int x0, int y0, int x1, int y1,lightCell power,std::function<lightCell(lightCell,int,int,int,int)> setPixel)
{ {
int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1; int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
int dy = -abs(y1-y0), sy = y0<y1 ? 1 : -1; int dy = -abs(y1-y0), sy = y0<y1 ? 1 : -1;
@ -231,8 +231,11 @@ void plotLine(int x0, int y0, int x1, int y1,std::function<bool(int,int,int,int)
int rdy=0; int rdy=0;
for(;;){ /* loop */ for(;;){ /* loop */
if(rdx!=0 || rdy!=0) //dirty hack to skip occlusion on the first tile. if(rdx!=0 || rdy!=0) //dirty hack to skip occlusion on the first tile.
if(!setPixel(rdx,rdy,x0,y0)) {
power=setPixel(power,rdx,rdy,x0,y0);
if(power.dot(power)<0.00001f)
return; return;
}
if (x0==x1 && y0==y1) break; if (x0==x1 && y0==y1) break;
e2 = 2*err; e2 = 2*err;
rdx=rdy=0; rdx=rdy=0;
@ -240,6 +243,56 @@ void plotLine(int x0, int y0, int x1, int y1,std::function<bool(int,int,int,int)
if (e2 <= dx) { err += dx; y0 += sy; rdy=sy;} /* e_xy+e_y < 0 */ if (e2 <= dx) { err += dx; y0 += sy; rdy=sy;} /* e_xy+e_y < 0 */
} }
} }
void plotLineAA(int x0, int y0, int x1, int y1,lightCell power,std::function<lightCell(lightCell,int,int,int,int)> setPixelAA)
{
int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
int err = dx-dy, e2, x2; /* error value e_xy */
int ed = dx+dy == 0 ? 1 : sqrt((float)dx*dx+(float)dy*dy);
int rdx=0;
int rdy=0;
int lrdx,lrdy;
lightCell sumPower;
for ( ; ; ){ /* pixel loop */
float strsum=0;
float str=1-abs(err-dx+dy)/(float)ed;
strsum=str;
sumPower=setPixelAA(power*str,rdx,rdy,x0,y0);
e2 = err; x2 = x0;
lrdx=rdx;
lrdy=rdy;
rdx=rdy=0;
if (2*e2 >= -dx) { /* x step */
if (x0 == x1) break;
if (e2+dy < ed)
{
str=1-(e2+dy)/(float)ed;
sumPower+=setPixelAA(power*str,lrdx,lrdy,x0,y0+sy);
strsum+=str;
}
err -= dy; x0 += sx; rdx=sx;
}
if (2*e2 <= dy) { /* y step */
if (y0 == y1) break;
if (dx-e2 < ed)
{
str=1-(dx-e2)/(float)ed;
sumPower+=setPixelAA(power*str,lrdx,lrdy,x2+sx,y0);
strsum+=str;
}
err += dx; y0 += sy; rdy=sy;
}
if(strsum<0.001f)
return;
sumPower=sumPower/strsum;
if(sumPower.dot(sumPower)<0.00001f)
return;
power=sumPower;
}
}
lightCell blendMax(lightCell a,lightCell b) lightCell blendMax(lightCell a,lightCell b)
{ {
return lightCell(std::max(a.r,b.r),std::max(a.g,b.g),std::max(a.b,b.b)); return lightCell(std::max(a.r,b.r),std::max(a.g,b.g),std::max(a.b,b.b));
@ -248,7 +301,7 @@ lightCell blend(lightCell a,lightCell b)
{ {
return blendMax(a,b); return blendMax(a,b);
} }
bool lightingEngineViewscreen::lightUpCell(std::vector<lightCell> & target, lightCell& power,int dx,int dy,int tx,int ty) lightCell lightingEngineViewscreen::lightUpCell(std::vector<lightCell> & target,lightCell power,int dx,int dy,int tx,int ty)
{ {
if(isInViewport(coord2d(tx,ty),mapPort)) if(isInViewport(coord2d(tx,ty),mapPort))
{ {
@ -271,12 +324,12 @@ bool lightingEngineViewscreen::lightUpCell(std::vector<lightCell> & target, ligh
if (dsq>0 && !wallhack) if (dsq>0 && !wallhack)
{ {
power*=v.power(dt); power*=v.pow(dt);
} }
if(ls.radius>0 && dsq>0) if(ls.radius>0 && dsq>0)
{ {
if(power<=ls.power) if(power<=ls.power)
return false; return lightCell();
} }
//float dt=sqrt(dsq); //float dt=sqrt(dsq);
lightCell oldCol=target[tile]; lightCell oldCol=target[tile];
@ -284,20 +337,20 @@ bool lightingEngineViewscreen::lightUpCell(std::vector<lightCell> & target, ligh
target[tile]=ncol; target[tile]=ncol;
if(wallhack) if(wallhack)
return false; return lightCell();
float pwsq=power.r*power.r+power.g*power.g+power.b*power.b;
return pwsq>levelDim*levelDim;
return power;
} }
else else
return false; return lightCell();
} }
void lightingEngineViewscreen::doRay(std::vector<lightCell> & target, lightCell power,int cx,int cy,int tx,int ty) void lightingEngineViewscreen::doRay(std::vector<lightCell> & target, lightCell power,int cx,int cy,int tx,int ty)
{ {
using namespace std::placeholders; using namespace std::placeholders;
lightCell curPower=power;
plotLine(cx,cy,tx,ty,std::bind(&lightingEngineViewscreen::lightUpCell,this,std::ref(target),std::ref(curPower),_1,_2,_3,_4)); plotLine(cx,cy,tx,ty,power,std::bind(&lightingEngineViewscreen::lightUpCell,this,std::ref(target),_1,_2,_3,_4,_5));
} }
void lightingEngineViewscreen::doLight(std::vector<lightCell> & target, int index) void lightingEngineViewscreen::doLight(std::vector<lightCell> & target, int index)
{ {
using namespace std::placeholders; using namespace std::placeholders;
@ -315,21 +368,21 @@ void lightingEngineViewscreen::doLight(std::vector<lightCell> & target, int inde
radius*=flicker; radius*=flicker;
power=power*flicker; power=power*flicker;
} }
int surrounds = 0; lightCell surrounds;
lightCell curPower;
lightUpCell(target, curPower = power, 0, 0,i+0, j+0); lightUpCell(target,power, 0, 0,i+0, j+0);
{ {
surrounds += lightUpCell(target, curPower = power, 0, 1,i+0, j+1); surrounds += lightUpCell(target, power, 0, 1,i+0, j+1);
surrounds += lightUpCell(target, curPower = power, 1, 1,i+1, j+1); surrounds += lightUpCell(target, power, 1, 1,i+1, j+1);
surrounds += lightUpCell(target, curPower = power, 1, 0,i+1, j+0); surrounds += lightUpCell(target, power, 1, 0,i+1, j+0);
surrounds += lightUpCell(target, curPower = power, 1,-1,i+1, j-1); surrounds += lightUpCell(target, power, 1,-1,i+1, j-1);
surrounds += lightUpCell(target, curPower = power, 0,-1,i+0, j-1); surrounds += lightUpCell(target, power, 0,-1,i+0, j-1);
surrounds += lightUpCell(target, curPower = power,-1,-1,i-1, j-1); surrounds += lightUpCell(target, power,-1,-1,i-1, j-1);
surrounds += lightUpCell(target, curPower = power,-1, 0,i-1, j+0); surrounds += lightUpCell(target, power,-1, 0,i-1, j+0);
surrounds += lightUpCell(target, curPower = power,-1, 1,i-1, j+1); surrounds += lightUpCell(target, power,-1, 1,i-1, j+1);
} }
if(surrounds) if(surrounds.dot(surrounds)>0.00001f)
{ {
plotSquare(i,j,radius, plotSquare(i,j,radius,
std::bind(&lightingEngineViewscreen::doRay,this,std::ref(target),power,i,j,_1,_2)); std::bind(&lightingEngineViewscreen::doRay,this,std::ref(target),power,i,j,_1,_2));
@ -365,7 +418,6 @@ void lightingEngineViewscreen::calculate()
} }
doOcupancyAndLights(); doOcupancyAndLights();
doFovs(); doFovs();
//for each lightsource in viewscreen+x do light
} }
void lightingEngineViewscreen::updateWindow() void lightingEngineViewscreen::updateWindow()
{ {
@ -405,7 +457,7 @@ void lightingEngineViewscreen::addOclusion(int tileId,const lightCell& c,float t
if(thickness > 0.999 && thickness < 1.001) if(thickness > 0.999 && thickness < 1.001)
ocupancy[tileId]*=c; ocupancy[tileId]*=c;
else else
ocupancy[tileId]*=(c.power(thickness)); ocupancy[tileId]*=(c.pow(thickness));
} }
lightCell getStandartColor(int colorId) lightCell getStandartColor(int colorId)
{ {
@ -496,7 +548,7 @@ lightCell lightingEngineViewscreen::propogateSun(MapExtras::Block* b, int x,int
ret*=matIce.transparency; ret*=matIce.transparency;
else if(basicShapeIce==df::tiletype_shape_basic::Floor || basicShapeIce==df::tiletype_shape_basic::Ramp || shapeIce==df::tiletype_shape::STAIR_UP) else if(basicShapeIce==df::tiletype_shape_basic::Floor || basicShapeIce==df::tiletype_shape_basic::Ramp || shapeIce==df::tiletype_shape::STAIR_UP)
if(!lastLevel) if(!lastLevel)
ret*=matIce.transparency.power(1.0f/7.0f); ret*=matIce.transparency.pow(1.0f/7.0f);
} }
lightDef=getMaterial(mat.mat_type,mat.mat_index); lightDef=getMaterial(mat.mat_type,mat.mat_index);
@ -511,7 +563,7 @@ lightCell lightingEngineViewscreen::propogateSun(MapExtras::Block* b, int x,int
{ {
if(!lastLevel) if(!lastLevel)
ret*=lightDef->transparency.power(1.0f/7.0f); ret*=lightDef->transparency.pow(1.0f/7.0f);
} }
else if(shape==df::tiletype_shape::STAIR_DOWN || shape==df::tiletype_shape::STAIR_UPDOWN) else if(shape==df::tiletype_shape::STAIR_DOWN || shape==df::tiletype_shape::STAIR_UPDOWN)
{ {
@ -519,11 +571,11 @@ lightCell lightingEngineViewscreen::propogateSun(MapExtras::Block* b, int x,int
} }
if(d.bits.liquid_type == df::enums::tile_liquid::Water && d.bits.flow_size > 0) if(d.bits.liquid_type == df::enums::tile_liquid::Water && d.bits.flow_size > 0)
{ {
ret *=matWater.transparency.power((float)d.bits.flow_size/7.0f); ret *=matWater.transparency.pow((float)d.bits.flow_size/7.0f);
} }
else if(d.bits.liquid_type == df::enums::tile_liquid::Magma && d.bits.flow_size > 0) else if(d.bits.liquid_type == df::enums::tile_liquid::Magma && d.bits.flow_size > 0)
{ {
ret *=matLava.transparency.power((float)d.bits.flow_size/7.0f); ret *=matLava.transparency.pow((float)d.bits.flow_size/7.0f);
} }
return ret; return ret;
} }
@ -626,7 +678,7 @@ void lightingEngineViewscreen::doOcupancyAndLights()
daycol= fmod(dayHour,24.0f)/24.0f; //1->12h 0->24h daycol= fmod(dayHour,24.0f)/24.0f; //1->12h 0->24h
lightCell sky_col=getSkyColor(daycol); lightCell sky_col=getSkyColor(daycol);
lightSource sky(sky_col, 15);//auto calculate best size lightSource sky(sky_col, -1);//auto calculate best size
lightSource candle(lightCell(0.96f,0.84f,0.03f),5); lightSource candle(lightCell(0.96f,0.84f,0.03f),5);
lightSource torch(lightCell(0.9f,0.75f,0.3f),8); lightSource torch(lightCell(0.9f,0.75f,0.3f),8);
@ -830,11 +882,15 @@ void lightingEngineViewscreen::doOcupancyAndLights()
df::coord2d p1(bld->x1,bld->y1); df::coord2d p1(bld->x1,bld->y1);
df::coord2d p2(bld->x2,bld->y2); df::coord2d p2(bld->x2,bld->y2);
p1=worldToViewportCoord(p1,vp,window2d); p1=worldToViewportCoord(p1,vp,window2d);
p2=worldToViewportCoord(p1,vp,window2d); p2=worldToViewportCoord(p2,vp,window2d);
if(isInViewport(p1,vp)||isInViewport(p2,vp)) if(isInViewport(p1,vp)||isInViewport(p2,vp))
{ {
int tile=getIndex(p1.x,p1.y); //TODO multitile buildings. How they would work? int tile;
if(isInViewport(p1,vp))
tile=getIndex(p1.x,p1.y); //TODO multitile buildings. How they would work?
else
tile=getIndex(p2.x,p2.y);
df::building_type type = bld->getType(); df::building_type type = bld->getType();
buildingLightDef* def=getBuilding(bld); buildingLightDef* def=getBuilding(bld);
if(!def) if(!def)

@ -114,7 +114,6 @@ struct matLightDef
matLightDef(lightCell transparency):isTransparent(true),isEmiting(false),transparency(transparency){} matLightDef(lightCell transparency):isTransparent(true),isEmiting(false),transparency(transparency){}
lightSource makeSource(float size=1) const lightSource makeSource(float size=1) const
{ {
//TODO implement sizeModifiesPower/range
if(size>0.999 && size<1.001) if(size>0.999 && size<1.001)
return lightSource(emitColor,radius); return lightSource(emitColor,radius);
else else
@ -152,7 +151,7 @@ private:
void doRay(std::vector<lightCell> & target, lightCell power,int cx,int cy,int tx,int ty); void doRay(std::vector<lightCell> & target, lightCell power,int cx,int cy,int tx,int ty);
void doFovs(); void doFovs();
void doLight(std::vector<lightCell> & target, int index); void doLight(std::vector<lightCell> & target, int index);
bool lightUpCell(std::vector<lightCell> & target, lightCell& power,int dx,int dy,int tx,int ty); lightCell lightUpCell(std::vector<lightCell> & target, lightCell power,int dx,int dy,int tx,int ty);
bool addLight(int tileId,const lightSource& light); bool addLight(int tileId,const lightSource& light);
void addOclusion(int tileId,const lightCell& c,float thickness); void addOclusion(int tileId,const lightCell& c,float thickness);

@ -196,7 +196,7 @@ struct lightCell
{ {
} }
lightCell operator-(lightCell cell) const lightCell operator-(const lightCell& cell) const
{ {
return lightCell(r-cell.r,g-cell.g,b-cell.b); return lightCell(r-cell.r,g-cell.g,b-cell.b);
} }
@ -208,17 +208,31 @@ struct lightCell
{ {
return lightCell(r/val,g/val,b/val); return lightCell(r/val,g/val,b/val);
} }
lightCell operator*(lightCell cell) const lightCell operator*(const lightCell& cell) const
{ {
return lightCell(r*cell.r,g*cell.g,b*cell.b); return lightCell(r*cell.r,g*cell.g,b*cell.b);
} }
lightCell operator*=(lightCell cell) lightCell operator*=(float val)
{
r*=val;
g*=val;
b*=val;
return *this;
}
lightCell operator*=(const lightCell& cell)
{ {
r*=cell.r; r*=cell.r;
g*=cell.g; g*=cell.g;
b*=cell.b; b*=cell.b;
return *this; return *this;
} }
lightCell operator+=(const lightCell& cell)
{
r+=cell.r;
g+=cell.g;
b+=cell.b;
return *this;
}
lightCell operator+(const lightCell& other) const lightCell operator+(const lightCell& other) const
{ {
return lightCell(r+other.r,g+other.g,b+other.b); return lightCell(r+other.r,g+other.g,b+other.b);
@ -231,13 +245,13 @@ struct lightCell
{ {
return r*other.r+g*other.g+b*other.b; return r*other.r+g*other.g+b*other.b;
} }
lightCell power(const float exp) const lightCell pow(const float exp) const
{ {
return lightCell(pow(r, exp), pow(g, exp), pow(b, exp)); return lightCell(std::pow(r, exp), std::pow(g, exp), std::pow(b, exp));
} }
lightCell power(const int exp) const lightCell pow(const int exp) const
{ {
return lightCell(pow(r, exp), pow(g, exp), pow(b, exp)); return lightCell(std::pow(r, exp), std::pow(g, exp), std::pow(b, exp));
} }
}; };
struct renderer_test : public renderer_wrap { struct renderer_test : public renderer_wrap {

@ -92,6 +92,16 @@ function makeMaterialDef(transparency,emitance,radius,flags)
end end
return {tr=transparency,em=emitance,rad=radius,flags=flg} return {tr=transparency,em=emitance,rad=radius,flags=flg}
end end
function colorFrom16(col16)
return copyall(df.global.enabler.ccolor[col16])
end
function addGems()
for k,v in pairs(df.global.world.raws.inorganics) do
if v.material.flags.IS_GEM then
addMaterial("INORGANIC:"..v.id,colorFrom16(v.material.build_color[0]))
end
end
end
------------------------------------------------------------------------ ------------------------------------------------------------------------
---------------- Configuration Starts Here ------------------------- ---------------- Configuration Starts Here -------------------------
------------------------------------------------------------------------ ------------------------------------------------------------------------
@ -128,7 +138,7 @@ addMaterial("PLANT:MUSHROOM_HELMET_PLUMP",nil,{0.2,0.1,0.6},2)
addMaterial("INORGANIC:ADAMANTINE",{0.1,0.3,0.3},{0.1,0.3,0.3},4) addMaterial("INORGANIC:ADAMANTINE",{0.1,0.3,0.3},{0.1,0.3,0.3},4)
-- creature stuff -- creature stuff
addMaterial("CREATURE:DRAGON:BLOOD",nil,{0.6,0.1,0.1},4) addMaterial("CREATURE:DRAGON:BLOOD",nil,{0.6,0.1,0.1},4)
-- TODO gems addGems()
--buildings --buildings
addBuilding("Statue",{1,1,1},{0.9,0.75,0.3},8) addBuilding("Statue",{1,1,1},{0.9,0.75,0.3},8)
addBuilding("Bed",{1,1,1},{0.3,0.2,0.0},2) addBuilding("Bed",{1,1,1},{0.3,0.2,0.0},2)