moved files around
This commit is contained in:
282
Extras/FCollada/FCDocument/FCDLight.cpp
Normal file
282
Extras/FCollada/FCDocument/FCDLight.cpp
Normal file
@@ -0,0 +1,282 @@
|
||||
/*
|
||||
Copyright (C) 2005-2006 Feeling Software Inc.
|
||||
MIT License: http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
/*
|
||||
Based on the FS Import classes:
|
||||
Copyright (C) 2005-2006 Feeling Software Inc
|
||||
Copyright (C) 2005-2006 Autodesk Media Entertainment
|
||||
MIT License: http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "FCDocument/FCDocument.h"
|
||||
#include "FCDocument/FCDAnimated.h"
|
||||
#include "FCDocument/FCDLight.h"
|
||||
#include "FCDocument/FCDSceneNode.h"
|
||||
#include "FUtils/FUStringConversion.h"
|
||||
#include "FUtils/FUDaeParser.h"
|
||||
#include "FUtils/FUDaeWriter.h"
|
||||
using namespace FUDaeParser;
|
||||
using namespace FUDaeWriter;
|
||||
|
||||
FCDLight::FCDLight(FCDocument* document) : FCDTargetedEntity(document, "Light")
|
||||
{
|
||||
color = FMVector3(1.0f, 1.0f, 1.0f);
|
||||
intensity = 1.0f;
|
||||
lightType = POINT;
|
||||
constantAttenuationFactor = linearAttenuationFactor = quadracticAttenuationFactor = 0.0f;
|
||||
fallOffExponent = 1.0f;
|
||||
outerAngle = fallOffAngle = 30.0f;
|
||||
penumbraAngle = 0.0f;
|
||||
dropoff = 10.0f;
|
||||
overshoots = true;
|
||||
}
|
||||
|
||||
FCDLight::~FCDLight()
|
||||
{
|
||||
}
|
||||
|
||||
// Load this light from the given COLLADA document's node
|
||||
FUStatus FCDLight::LoadFromXML(xmlNode* lightNode)
|
||||
{
|
||||
FUStatus status = FCDEntity::LoadFromXML(lightNode);
|
||||
if (!status) return status;
|
||||
if (!IsEquivalent(lightNode->name, DAE_LIGHT_ELEMENT))
|
||||
{
|
||||
return status.Warning(FS("Light library contains unknown element."), lightNode->line);
|
||||
}
|
||||
|
||||
// Grab the <technique_common> element. If not present, assume COLLADA 1.3
|
||||
xmlNode* commonTechniqueNode = FindChildByType(lightNode, DAE_TECHNIQUE_COMMON_ELEMENT);
|
||||
bool isCollada1_3 = commonTechniqueNode == NULL;
|
||||
xmlNode* maxTechniqueNode = FindTechnique(lightNode, DAEMAX_MAX_PROFILE);
|
||||
xmlNode* mayaTechniqueNode = FindTechnique(lightNode, DAEMAYA_MAYA_PROFILE);
|
||||
|
||||
// Create the correct light source
|
||||
xmlNode* lightParameterNode = NULL;
|
||||
if (isCollada1_3)
|
||||
{
|
||||
// COLLADA 1.3 backward-compatibility: read the 'type' attribute of the <light> element
|
||||
string type = ReadNodeProperty(lightNode, DAE_TYPE_ATTRIBUTE);
|
||||
if (type == DAE_AMBIENT_LIGHT_TYPE) lightType = AMBIENT;
|
||||
else if (type == DAE_DIRECTIONAL_LIGHT_TYPE) lightType = DIRECTIONAL;
|
||||
else if (type == DAE_POINT_LIGHT_TYPE) lightType = POINT;
|
||||
else if (type == DAE_SPOT_LIGHT_TYPE) lightType = SPOT;
|
||||
else
|
||||
{
|
||||
status.Warning(FS("Unknown light type value for light: ") + TO_FSTRING(GetDaeId()), lightNode->line);
|
||||
}
|
||||
|
||||
// COLLADA 1.3.2 backward-compatibility: look for this hack for the parameters under a common-profile technique
|
||||
lightParameterNode = FindTechnique(lightNode, DAE_COMMON_PROFILE);
|
||||
if (lightParameterNode == NULL) lightParameterNode = lightNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Look for the <point>, <directional>, <spot> or <ambient> element under the common-profile technique
|
||||
for (xmlNode* child = commonTechniqueNode->children; child != NULL; child = child->next)
|
||||
{
|
||||
if (child->type != XML_ELEMENT_NODE) continue;
|
||||
if (IsEquivalent(child->name, DAE_LIGHT_POINT_ELEMENT)) { lightParameterNode = child; lightType = POINT; break; }
|
||||
else if (IsEquivalent(child->name, DAE_LIGHT_SPOT_ELEMENT)) { lightParameterNode = child; lightType = SPOT; break; }
|
||||
else if (IsEquivalent(child->name, DAE_LIGHT_AMBIENT_ELEMENT)) { lightParameterNode = child; lightType = AMBIENT; break; }
|
||||
else if (IsEquivalent(child->name, DAE_LIGHT_DIRECTIONAL_ELEMENT)) { lightParameterNode = child; lightType = DIRECTIONAL; break; }
|
||||
else
|
||||
{
|
||||
status.Warning(FS("Unknown element under <light><technique_common> for light: ") + TO_FSTRING(GetDaeId()), child->line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the light's basic structures are found
|
||||
if (lightParameterNode == NULL)
|
||||
{
|
||||
return status.Fail(FS("Unable to find the parameter root node for light: ") + TO_FSTRING(GetDaeId()), lightNode->line);
|
||||
}
|
||||
|
||||
// Retrieve the light parameters
|
||||
StringList parameterNames;
|
||||
xmlNodeList parameterNodes;
|
||||
FindParameters(lightParameterNode, parameterNames, parameterNodes);
|
||||
FindParameters(maxTechniqueNode, parameterNames, parameterNodes);
|
||||
FindParameters(mayaTechniqueNode, parameterNames, parameterNodes);
|
||||
xmlNode* extraNode = FindChildByType(lightNode, DAE_EXTRA_ELEMENT);
|
||||
xmlNode* maxExtraNode = FindTechnique(extraNode, DAEMAX_MAX_PROFILE);
|
||||
FindParameters(maxExtraNode, parameterNames, parameterNodes);
|
||||
|
||||
// Parse the light parameters
|
||||
FUDaeFunction::Function attenuationFunction = FUDaeFunction::CONSTANT;
|
||||
float attenuationFactor = 0.0f;
|
||||
xmlNode* attenuationFactorNode = NULL;
|
||||
|
||||
size_t parameterCount = parameterNodes.size();
|
||||
for (size_t i = 0; i < parameterCount; ++i)
|
||||
{
|
||||
xmlNode* parameterNode = parameterNodes[i];
|
||||
const string& parameterName = parameterNames[i];
|
||||
const char* content = ReadNodeContentDirect(parameterNode);
|
||||
if (parameterName == DAE_COLOR_LIGHT_PARAMETER || parameterName == DAE_COLOR_LIGHT_PARAMETER1_3)
|
||||
{
|
||||
color = FUStringConversion::ToPoint(content);
|
||||
FCDAnimatedColor::Create(GetDocument(), parameterNode, &color);
|
||||
}
|
||||
else if (parameterName == DAE_CONST_ATTENUATION_LIGHT_PARAMETER)
|
||||
{
|
||||
constantAttenuationFactor = FUStringConversion::ToFloat(content);
|
||||
FCDAnimatedFloat::Create(GetDocument(), parameterNode, &constantAttenuationFactor);
|
||||
}
|
||||
else if (parameterName == DAE_LIN_ATTENUATION_LIGHT_PARAMETER)
|
||||
{
|
||||
linearAttenuationFactor = FUStringConversion::ToFloat(content);
|
||||
FCDAnimatedFloat::Create(GetDocument(), parameterNode, &linearAttenuationFactor);
|
||||
}
|
||||
else if (parameterName == DAE_QUAD_ATTENUATION_LIGHT_PARAMETER)
|
||||
{
|
||||
quadracticAttenuationFactor = FUStringConversion::ToFloat(content);
|
||||
FCDAnimatedFloat::Create(GetDocument(), parameterNode, &quadracticAttenuationFactor);
|
||||
}
|
||||
else if (parameterName == DAE_ATTENUATION_LIGHT_PARAMETER1_3)
|
||||
{
|
||||
attenuationFunction = FUDaeFunction::FromString(content);
|
||||
}
|
||||
else if (parameterName == DAE_ATTENUATIONSCALE_LIGHT_PARAMETER1_3)
|
||||
{
|
||||
attenuationFactor = FUStringConversion::ToFloat(content);
|
||||
attenuationFactorNode = parameterNode;
|
||||
}
|
||||
else if (parameterName == DAE_FALLOFFEXPONENT_LIGHT_PARAMETER)
|
||||
{
|
||||
fallOffExponent = FUStringConversion::ToFloat(content);
|
||||
FCDAnimatedFloat::Create(GetDocument(), parameterNode, &fallOffExponent);
|
||||
}
|
||||
else if (parameterName == DAE_FALLOFF_LIGHT_PARAMETER1_3)
|
||||
{
|
||||
fallOffExponent = (float) FUDaeFunction::FromString(content);
|
||||
}
|
||||
else if (parameterName == DAE_FALLOFFANGLE_LIGHT_PARAMETER || parameterName == DAE_ANGLE_LIGHT_PARAMETER1_3)
|
||||
{
|
||||
fallOffAngle = FUStringConversion::ToFloat(content);
|
||||
FCDAnimatedFloat::Create(GetDocument(), parameterNode, &fallOffAngle);
|
||||
}
|
||||
else if (parameterName == DAESHD_INTENSITY_LIGHT_PARAMETER || parameterName == DAESHD_INTENSITY_LIGHT_PARAMETER1_3)
|
||||
{
|
||||
intensity = FUStringConversion::ToFloat(content);
|
||||
FCDAnimatedFloat::Create(GetDocument(), parameterNode, &intensity);
|
||||
}
|
||||
else if (parameterName == DAEMAX_OUTERCONE_LIGHT_PARAMETER || parameterName == DAEMAX_OUTERCONE_LIGHT_PARAMETER1_3)
|
||||
{
|
||||
outerAngle = FUStringConversion::ToFloat(content);
|
||||
FCDAnimatedFloat::Create(GetDocument(), parameterNode, &outerAngle);
|
||||
}
|
||||
else if (parameterName == DAEMAX_OVERSHOOT_LIGHT_PARAMETER || parameterName == DAEMAX_OVERSHOOT_LIGHT_PARAMETER1_3)
|
||||
{
|
||||
overshoots = FUStringConversion::ToBoolean(content);
|
||||
}
|
||||
else if (parameterName == DAEMAX_TARGET_LIGHT_PARAMETER || parameterName == DAEMAX_TARGET_LIGHT_PARAMETER1_3)
|
||||
{
|
||||
SetTargetId(content);
|
||||
}
|
||||
else if (parameterName == DAEMAYA_PENUMBRA_LIGHT_PARAMETER || parameterName == DAEMAYA_PENUMBRA_LIGHT_PARAMETER1_3)
|
||||
{
|
||||
penumbraAngle = FUStringConversion::ToFloat(content);
|
||||
FCDAnimatedFloat::Create(GetDocument(), parameterNode, &penumbraAngle);
|
||||
}
|
||||
else if (parameterName == DAEMAYA_DROPOFF_LIGHT_PARAMETER || parameterName == DAE_FALLOFFSCALE_LIGHT_PARAMETER1_3)
|
||||
{
|
||||
dropoff = FUStringConversion::ToFloat(content);
|
||||
FCDAnimatedFloat::Create(GetDocument(), parameterNode, &dropoff);
|
||||
}
|
||||
else if (parameterName == DAEMAX_ASPECTRATIO_LIGHT_PARAMETER || parameterName == DAEMAX_ASPECTRATIO_LIGHT_PARAMETER1_3)
|
||||
{
|
||||
aspectRatio = FUStringConversion::ToFloat(content);
|
||||
FCDAnimatedFloat::Create(GetDocument(), parameterNode, &aspectRatio);
|
||||
}
|
||||
else
|
||||
{
|
||||
status.Warning(FS("Unknown program parameter for light: ") + TO_FSTRING(GetDaeId()), parameterNode->line);
|
||||
}
|
||||
}
|
||||
|
||||
if (attenuationFactorNode != NULL)
|
||||
{
|
||||
// Match the deprecated COLLADA 1.3 parameter's animation to the correct, new attenuation factor
|
||||
switch (attenuationFunction)
|
||||
{
|
||||
case FUDaeFunction::CONSTANT:
|
||||
constantAttenuationFactor = attenuationFactor;
|
||||
FCDAnimatedFloat::Create(GetDocument(), attenuationFactorNode, &constantAttenuationFactor);
|
||||
break;
|
||||
case FUDaeFunction::LINEAR:
|
||||
linearAttenuationFactor = attenuationFactor;
|
||||
FCDAnimatedFloat::Create(GetDocument(), attenuationFactorNode, &linearAttenuationFactor);
|
||||
break;
|
||||
case FUDaeFunction::QUADRATIC:
|
||||
quadracticAttenuationFactor = attenuationFactor;
|
||||
FCDAnimatedFloat::Create(GetDocument(), attenuationFactorNode, &quadracticAttenuationFactor);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
// Write out this light to the COLLADA XML document
|
||||
xmlNode* FCDLight::WriteToXML(xmlNode* parentNode) const
|
||||
{
|
||||
// Create the base light node
|
||||
xmlNode* lightNode = WriteToEntityXML(parentNode, DAE_LIGHT_ELEMENT);
|
||||
xmlNode* baseNode = AddChild(lightNode, DAE_TECHNIQUE_COMMON_ELEMENT);
|
||||
const char* baseNodeName;
|
||||
switch (lightType)
|
||||
{
|
||||
case POINT: baseNodeName = DAE_LIGHT_POINT_ELEMENT; break;
|
||||
case SPOT: baseNodeName = DAE_LIGHT_SPOT_ELEMENT; break;
|
||||
case AMBIENT: baseNodeName = DAE_LIGHT_AMBIENT_ELEMENT; break;
|
||||
case DIRECTIONAL: baseNodeName = DAE_LIGHT_DIRECTIONAL_ELEMENT; break;
|
||||
default: baseNodeName = DAEERR_UNKNOWN_INPUT; break;
|
||||
}
|
||||
baseNode = AddChild(baseNode, baseNodeName);
|
||||
|
||||
// Add the application-specific technique
|
||||
xmlNode* techniqueMayaNode = AddTechniqueChild(lightNode, DAEMAYA_MAYA_PROFILE);
|
||||
xmlNode* techniqueMaxNode = AddTechniqueChild(lightNode, DAEMAX_MAX_PROFILE);
|
||||
|
||||
// Write out the light parameters
|
||||
string colorValue = FUStringConversion::ToString(color);
|
||||
xmlNode* colorNode = AddChild(baseNode, DAE_COLOR_LIGHT_PARAMETER, colorValue);
|
||||
GetDocument()->WriteAnimatedValueToXML(&color.x, colorNode, "color");
|
||||
|
||||
xmlNode* attenuationBaseNode = (lightType == POINT || lightType == SPOT) ? baseNode : techniqueMaxNode;
|
||||
xmlNode* attenuationNode = AddChild(attenuationBaseNode, DAE_CONST_ATTENUATION_LIGHT_PARAMETER, constantAttenuationFactor);
|
||||
GetDocument()->WriteAnimatedValueToXML(&constantAttenuationFactor, attenuationNode, "constant_attenuation");
|
||||
attenuationNode = AddChild(attenuationBaseNode, DAE_LIN_ATTENUATION_LIGHT_PARAMETER, linearAttenuationFactor);
|
||||
GetDocument()->WriteAnimatedValueToXML(&linearAttenuationFactor, attenuationNode, "linear_attenuation");
|
||||
attenuationNode = AddChild(attenuationBaseNode, DAE_QUAD_ATTENUATION_LIGHT_PARAMETER, quadracticAttenuationFactor);
|
||||
GetDocument()->WriteAnimatedValueToXML(&quadracticAttenuationFactor, attenuationNode, "quadratic_attenuation");
|
||||
|
||||
xmlNode* falloffBaseNode = (lightType == SPOT) ? baseNode : techniqueMaxNode;
|
||||
xmlNode* falloffNode = AddChild(falloffBaseNode, DAE_FALLOFFANGLE_LIGHT_PARAMETER, fallOffAngle);
|
||||
GetDocument()->WriteAnimatedValueToXML(&fallOffAngle, falloffNode, "falloff_angle");
|
||||
falloffNode = AddChild(falloffBaseNode, DAE_FALLOFFEXPONENT_LIGHT_PARAMETER, fallOffExponent);
|
||||
GetDocument()->WriteAnimatedValueToXML(&fallOffExponent, falloffNode, "falloff_exponent");
|
||||
|
||||
xmlNode* intensityNode = AddChild(techniqueMaxNode, DAESHD_INTENSITY_LIGHT_PARAMETER, intensity);
|
||||
AddChild(techniqueMayaNode, DAESHD_INTENSITY_LIGHT_PARAMETER, intensity);
|
||||
GetDocument()->WriteAnimatedValueToXML(&intensity, intensityNode, "intensity");
|
||||
xmlNode* outerAngleNode = AddChild(techniqueMaxNode, DAEMAX_OUTERCONE_LIGHT_PARAMETER, outerAngle);
|
||||
GetDocument()->WriteAnimatedValueToXML(&outerAngle, outerAngleNode, "outer_angle");
|
||||
xmlNode* penumbraAngleNode = AddChild(techniqueMayaNode, DAEMAYA_PENUMBRA_LIGHT_PARAMETER, penumbraAngle);
|
||||
GetDocument()->WriteAnimatedValueToXML(&penumbraAngle, penumbraAngleNode, "penumbra_angle");
|
||||
xmlNode* aspectRatioNode = AddChild(techniqueMaxNode, DAEMAX_ASPECTRATIO_LIGHT_PARAMETER, aspectRatio);
|
||||
GetDocument()->WriteAnimatedValueToXML(&aspectRatio, aspectRatioNode, "aspect_ratio");
|
||||
xmlNode* dropoffNode = AddChild(techniqueMayaNode, DAEMAYA_DROPOFF_LIGHT_PARAMETER, dropoff);
|
||||
GetDocument()->WriteAnimatedValueToXML(&dropoff, dropoffNode, "dropoff");
|
||||
AddChild(techniqueMaxNode, DAEMAX_OVERSHOOT_LIGHT_PARAMETER, overshoots);
|
||||
|
||||
if (GetTargetNode() != NULL) AddChild(techniqueMaxNode, DAEMAX_TARGET_LIGHT_PARAMETER, GetTargetNode()->GetDaeId());
|
||||
|
||||
FCDEntity::WriteToExtraXML(lightNode);
|
||||
return lightNode;
|
||||
}
|
||||
Reference in New Issue
Block a user