COLLADA lights:
* simplify export and import, now that we have blender profiles for lights. The vanilla import is now more in line with the specs. If a blender profile is found, skip normal import, use the profile data instead. * multiply energy into color rgb export (common profile). * recalc distance taking metrics in account
This commit is contained in:
@@ -863,109 +863,35 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light )
|
||||
{
|
||||
if(mImportStage!=General)
|
||||
return true;
|
||||
|
||||
|
||||
Lamp *lamp = NULL;
|
||||
std::string la_id, la_name;
|
||||
|
||||
|
||||
TagsMap::iterator etit;
|
||||
ExtraTags *et = 0;
|
||||
etit = uid_tags_map.find(light->getUniqueId().toAscii());
|
||||
if(etit != uid_tags_map.end())
|
||||
et = etit->second;
|
||||
|
||||
|
||||
la_id = light->getOriginalId();
|
||||
la_name = light->getName();
|
||||
if (la_name.size()) lamp = (Lamp*)add_lamp((char*)la_name.c_str());
|
||||
else lamp = (Lamp*)add_lamp((char*)la_id.c_str());
|
||||
|
||||
|
||||
if (!lamp) {
|
||||
fprintf(stderr, "Cannot create lamp. \n");
|
||||
return true;
|
||||
}
|
||||
if (light->getColor().isValid()) {
|
||||
COLLADAFW::Color col = light->getColor();
|
||||
lamp->r = col.getRed();
|
||||
lamp->g = col.getGreen();
|
||||
lamp->b = col.getBlue();
|
||||
}
|
||||
float constatt = light->getConstantAttenuation().getValue();
|
||||
float linatt = light->getLinearAttenuation().getValue();
|
||||
float quadatt = light->getQuadraticAttenuation().getValue();
|
||||
float d = 25.0f;
|
||||
float att1 = 0.0f;
|
||||
float att2 = 0.0f;
|
||||
|
||||
float e = 1.0f/constatt;
|
||||
|
||||
/* NOTE: We assume for now that inv square is used for quadratic light
|
||||
* and inv linear for linear light. Exported blender lin/quad weighted
|
||||
* most likely will result in wrong import. */
|
||||
/* quadratic light */
|
||||
if(IS_EQ(linatt, 0.0f) && quadatt > 0.0f) {
|
||||
//quadatt = att2/(d*d*(e*2));
|
||||
float invquadatt = 1.0f/quadatt;
|
||||
float d2 = invquadatt / (2 * e);
|
||||
d = sqrtf(d2);
|
||||
}
|
||||
// linear light
|
||||
else if(IS_EQ(quadatt, 0.0f) && linatt > 0.0f) {
|
||||
//linatt = att1/(d*e);
|
||||
float invlinatt = 1.0f/linatt;
|
||||
d = invlinatt / e;
|
||||
} else {
|
||||
printf("no linear nor quad light, using defaults for attenuation, import will be incorrect: Lamp %s\n", lamp->id.name);
|
||||
att2 = 1.0f;
|
||||
}
|
||||
|
||||
lamp->dist = d;
|
||||
lamp->energy = e;
|
||||
|
||||
COLLADAFW::Light::LightType type = light->getLightType();
|
||||
switch(type) {
|
||||
case COLLADAFW::Light::AMBIENT_LIGHT:
|
||||
{
|
||||
lamp->type = LA_HEMI;
|
||||
}
|
||||
break;
|
||||
case COLLADAFW::Light::SPOT_LIGHT:
|
||||
{
|
||||
lamp->type = LA_SPOT;
|
||||
lamp->falloff_type = LA_FALLOFF_INVSQUARE;
|
||||
lamp->att1 = att1;
|
||||
lamp->att2 = att2;
|
||||
lamp->spotsize = light->getFallOffAngle().getValue();
|
||||
lamp->spotblend = light->getFallOffExponent().getValue();
|
||||
}
|
||||
break;
|
||||
case COLLADAFW::Light::DIRECTIONAL_LIGHT:
|
||||
{
|
||||
/* our sun is very strong, so pick a smaller energy level */
|
||||
lamp->type = LA_SUN;
|
||||
lamp->energy = 1.0;
|
||||
lamp->mode |= LA_NO_SPEC;
|
||||
}
|
||||
break;
|
||||
case COLLADAFW::Light::POINT_LIGHT:
|
||||
{
|
||||
lamp->type = LA_LOCAL;
|
||||
lamp->falloff_type = LA_FALLOFF_INVSQUARE;
|
||||
lamp->att1 = att1;
|
||||
lamp->att2 = att2;
|
||||
}
|
||||
break;
|
||||
case COLLADAFW::Light::UNDEFINED:
|
||||
{
|
||||
fprintf(stderr, "Current lamp type is not supported. \n");
|
||||
lamp->type = LA_LOCAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(et) {
|
||||
|
||||
// if we find an ExtraTags for this, use that instead.
|
||||
if(et && et->isProfile("blender")) {
|
||||
et->setData("type", &(lamp->type));
|
||||
et->setData("flag", &(lamp->flag));
|
||||
et->setData("mode", &(lamp->mode));
|
||||
et->setData("gamma", &(lamp->k));
|
||||
et->setData("red", &(lamp->r));
|
||||
et->setData("green", &(lamp->g));
|
||||
et->setData("blue", &(lamp->b));
|
||||
et->setData("shadow_r", &(lamp->shdwr));
|
||||
et->setData("shadow_g", &(lamp->shdwg));
|
||||
et->setData("shadow_b", &(lamp->shdwb));
|
||||
@@ -1015,7 +941,83 @@ bool DocumentImporter::writeLight( const COLLADAFW::Light* light )
|
||||
et->setData("sky_exposure", &(lamp->sky_exposure));
|
||||
et->setData("sky_colorspace", &(lamp->sky_colorspace));
|
||||
}
|
||||
else {
|
||||
float constatt = light->getConstantAttenuation().getValue();
|
||||
float linatt = light->getLinearAttenuation().getValue();
|
||||
float quadatt = light->getQuadraticAttenuation().getValue();
|
||||
float d = 25.0f;
|
||||
float att1 = 0.0f;
|
||||
float att2 = 0.0f;
|
||||
float e = 1.0f;
|
||||
|
||||
if (light->getColor().isValid()) {
|
||||
COLLADAFW::Color col = light->getColor();
|
||||
lamp->r = col.getRed();
|
||||
lamp->g = col.getGreen();
|
||||
lamp->b = col.getBlue();
|
||||
}
|
||||
|
||||
if(IS_EQ(linatt, 0.0f) && quadatt > 0.0f) {
|
||||
att2 = quadatt;
|
||||
d = (1.0f/quadatt) * 2;
|
||||
}
|
||||
// linear light
|
||||
else if(IS_EQ(quadatt, 0.0f) && linatt > 0.0f) {
|
||||
att1 = linatt;
|
||||
d = (1.0f/linatt) * 2;
|
||||
} else if (IS_EQ(constatt, 1.0f)) {
|
||||
att1 = 1.0f;
|
||||
} else {
|
||||
// assuming point light (const att = 1.0);
|
||||
att1 = 1.0f;
|
||||
}
|
||||
|
||||
d *= ( 1.0f / unit_converter.getLinearMeter());
|
||||
|
||||
lamp->energy = e;
|
||||
lamp->dist = d;
|
||||
|
||||
COLLADAFW::Light::LightType type = light->getLightType();
|
||||
switch(type) {
|
||||
case COLLADAFW::Light::AMBIENT_LIGHT:
|
||||
{
|
||||
lamp->type = LA_HEMI;
|
||||
}
|
||||
break;
|
||||
case COLLADAFW::Light::SPOT_LIGHT:
|
||||
{
|
||||
lamp->type = LA_SPOT;
|
||||
lamp->falloff_type = LA_FALLOFF_INVSQUARE;
|
||||
lamp->att1 = att1;
|
||||
lamp->att2 = att2;
|
||||
lamp->spotsize = light->getFallOffAngle().getValue();
|
||||
lamp->spotblend = light->getFallOffExponent().getValue();
|
||||
}
|
||||
break;
|
||||
case COLLADAFW::Light::DIRECTIONAL_LIGHT:
|
||||
{
|
||||
/* our sun is very strong, so pick a smaller energy level */
|
||||
lamp->type = LA_SUN;
|
||||
lamp->mode |= LA_NO_SPEC;
|
||||
}
|
||||
break;
|
||||
case COLLADAFW::Light::POINT_LIGHT:
|
||||
{
|
||||
lamp->type = LA_LOCAL;
|
||||
lamp->falloff_type = LA_FALLOFF_INVSQUARE;
|
||||
lamp->att1 = att1;
|
||||
lamp->att2 = att2;
|
||||
}
|
||||
break;
|
||||
case COLLADAFW::Light::UNDEFINED:
|
||||
{
|
||||
fprintf(stderr, "Current lamp type is not supported. \n");
|
||||
lamp->type = LA_LOCAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this->uid_lamp_map[light->getUniqueId()] = lamp;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,11 @@ ExtraTags::~ExtraTags()
|
||||
{
|
||||
}
|
||||
|
||||
bool ExtraTags::isProfile( std::string profile)
|
||||
{
|
||||
return this->profile == profile;
|
||||
}
|
||||
|
||||
bool ExtraTags::addTag( std::string tag, std::string data)
|
||||
{
|
||||
tags[tag] = data;
|
||||
|
||||
@@ -56,6 +56,9 @@ public:
|
||||
/** Set given char pointer to value of tag, if it exists. */
|
||||
void setData(std::string tag, char *data);
|
||||
|
||||
/** Return true if the extra tags is for specified profile. */
|
||||
bool isProfile(std::string profile);
|
||||
|
||||
private:
|
||||
/** Disable default copy constructor. */
|
||||
ExtraTags( const ExtraTags& pre );
|
||||
|
||||
@@ -66,32 +66,22 @@ void LightsExporter::operator()(Object *ob)
|
||||
Lamp *la = (Lamp*)ob->data;
|
||||
std::string la_id(get_light_id(ob));
|
||||
std::string la_name(id_name(la));
|
||||
COLLADASW::Color col(la->r, la->g, la->b);
|
||||
float att1, att2;
|
||||
COLLADASW::Color col(la->r * la->energy, la->g * la->energy, la->b * la->energy);
|
||||
float e, d, constatt, linatt, quadatt;
|
||||
att1 = att2 = 0.0f;
|
||||
float r;
|
||||
|
||||
d = la->dist;
|
||||
r = d/2.0f;
|
||||
|
||||
constatt = 1.0f;
|
||||
|
||||
if(la->falloff_type==LA_FALLOFF_INVLINEAR) {
|
||||
att1 = 1.0f;
|
||||
att2 = 0.0f;
|
||||
linatt = 1.0f / r;
|
||||
quadatt = 0.0f;
|
||||
}
|
||||
else if(la->falloff_type==LA_FALLOFF_INVSQUARE) {
|
||||
att1 = 0.0f;
|
||||
att2 = 1.0f;
|
||||
}
|
||||
else if(la->falloff_type==LA_FALLOFF_SLIDERS) {
|
||||
att1 = la->att1;
|
||||
att2 = la->att2;
|
||||
}
|
||||
|
||||
e = la->energy;
|
||||
d = la->dist;
|
||||
|
||||
constatt = linatt = quadatt = MAXFLOAT;
|
||||
if(e > 0.0f) {
|
||||
constatt = 1.0f/e;
|
||||
linatt = att1/(d*e);
|
||||
quadatt = att2/(d*d*(e*2));
|
||||
else {
|
||||
linatt = 0.0f;
|
||||
quadatt = 1.0f / r;
|
||||
}
|
||||
|
||||
// sun
|
||||
@@ -152,6 +142,9 @@ bool LightsExporter::exportBlenderProfile(COLLADASW::Light &cla, Lamp *la)
|
||||
cla.addExtraTechniqueParameter("blender", "flag", la->flag);
|
||||
cla.addExtraTechniqueParameter("blender", "mode", la->mode);
|
||||
cla.addExtraTechniqueParameter("blender", "gamma", la->k);
|
||||
cla.addExtraTechniqueParameter("blender", "red", la->r);
|
||||
cla.addExtraTechniqueParameter("blender", "green", la->g);
|
||||
cla.addExtraTechniqueParameter("blender", "blue", la->b);
|
||||
cla.addExtraTechniqueParameter("blender", "shadow_r", la->shdwr);
|
||||
cla.addExtraTechniqueParameter("blender", "shadow_g", la->shdwg);
|
||||
cla.addExtraTechniqueParameter("blender", "shadow_b", la->shdwb);
|
||||
|
||||
Reference in New Issue
Block a user