void SpotLightFalloffManipulator::UpdateShapes(TimeValue t, TSTR& toolTip) { GenLight* pLight = (GenLight*) mhTarget; Matrix3 tm; tm = mpINode->GetObjectTM(t); Point3 pt; b = GetTargetPoint(t, pt); if (!b) return; float den = FLength(tm.GetRow(2)); float dist = (den!=0) ? FLength(tm.GetTrans()-pt) / den : 0.0f; TSTR nodeName; nodeName = mpINode->GetName(); tm = Inverse(tm); toolTip.printf("Falloff: %5.2f", (double) pLight->GetFallsize(t)); SetGizmoScale(dist / kRingScaleFactor); ConeAngleManipulator::UpdateShapes(Point3(0,0,0), Point3(0,0,-1), dist, pLight->GetFallsize(t)); }
void SpotLightMultiplierManipulator::UpdateShapes(TimeValue t, TSTR& toolTip) { GenLight* pLight = (GenLight*) mhTarget; Matrix3 tm; tm = mpINode->GetObjectTM(t); Point3 pt; b = GetTargetPoint(t, pt); if (!b) return; TSTR nodeName; nodeName = mpINode->GetName(); float den = FLength(tm.GetRow(2)); float targetDist = (den!=0) ? FLength(tm.GetTrans()-pt) / den : 0.0f; toolTip.printf("%s: %5.2f", "Multiplier", (double) pLight->GetIntensity(t)); SetGizmoScale(targetDist / 40.0); float dist = (targetDist / 2.0) * pLight->GetIntensity(t); ConeDistanceManipulator::UpdateShapes(Point3(0,0,0), Point3(0,0,-1), dist, pLight->GetFallsize(t), true); }
void SpotLightAttenuationManipulator::UpdateShapes(TimeValue t, TSTR& toolTip) { GenLight* pLight = (GenLight*) mhTarget; Matrix3 tm; tm = mpINode->GetObjectTM(t); Point3 pt; b = GetTargetPoint(t, pt); if (!b) return; float dist = pLight->GetAtten(t, mAttenuationType); TSTR nodeName; nodeName = mpINode->GetName(); float den = FLength(tm.GetRow(2)); float targetDist = (den!=0) ? FLength(tm.GetTrans()-pt) / den : 0.0f; toolTip.printf("%s: %5.2f", mAttenName.data(), (double) dist); SetGizmoScale(targetDist / 40.0); ConeDistanceManipulator::UpdateShapes(Point3(0,0,0), Point3(0,0,-1), dist, pLight->GetFallsize(t), false); }
void SpotLightHotSpotManipulator::SetAngle(float angle) { GenLight* pLight = (GenLight*) mhTarget; TimeValue t = GetCOREInterface()->GetTime(); float fall = pLight->GetFallsize(t); SetHotAndFall(angle, fall, pLight, TRUE); }
void SpotLightFalloffManipulator::SetAngle(float angle) { GenLight* pLight = (GenLight*) mhTarget; TimeValue t = GetCOREInterface()->GetTime(); float hot = pLight->GetFalloff(t); SetHotAndFall(hot, angle, pLight, FALSE); }
void CExportNel::getLights (std::vector<CLight>& vectLight, TimeValue time, INode* node) { // Get the root node if (node==NULL) node=_Ip->GetRootNode(); // Get a pointer on the object's node ObjectState os = node->EvalWorldState(time); Object *obj = os.obj; // Check if there is an object if (obj) { // Get a GenLight from the node if (obj->SuperClassID()==LIGHT_CLASS_ID) { /*GenLight *maxLight = (GenLight *) obj->ConvertToType(time, Class_ID(OMNI_LIGHT_CLASS_ID , 0)); if (!maxLight) maxLight = (GenLight *) obj->ConvertToType(time, Class_ID(SPOT_LIGHT_CLASS_ID, 0)); if (!maxLight) maxLight = (GenLight *) obj->ConvertToType(time, Class_ID(DIR_LIGHT_CLASS_ID, 0)); if (!maxLight) maxLight = (GenLight *) obj->ConvertToType(time, Class_ID(FSPOT_LIGHT_CLASS_ID, 0)); if (!maxLight) maxLight = (GenLight *) obj->ConvertToType(time, Class_ID(TDIR_LIGHT_CLASS_ID, 0));*/ //if (maxLight) GenLight *maxLight = (GenLight *) obj; // Note that the TriObject should only be deleted // if the pointer to it is not equal to the object // pointer that called ConvertToType() bool deleteIt=false; if (obj != maxLight) deleteIt = true; // Build a light CLight nelLight; // If build succesful if (buildLight (*maxLight, nelLight, *node, time)) // Add the light in the list vectLight.push_back (nelLight); // Delete the GenLight if we should... if (deleteIt) maxLight->DeleteThis(); } } // Recurse sub node for (int i=0; i<node->NumberOfChildren(); i++) getLights (vectLight, time, node->GetChildNode(i)); }
void SpotLightFalloffManipulator::UpdateShapes(TimeValue t, TSTR& toolTip) { GenLight* pLight = (GenLight*) mhTarget; Matrix3 tm; tm = mpINode->GetObjectTM(t); Point3 pt; float dist; BOOL b = GetTargetPoint(t, pt); if (!b) { dist = pLight->GetTDist(t); } else { float den = FLength(tm.GetRow(2)); dist = (den!=0) ? FLength(tm.GetTrans()-pt) / den : 0.0f; } TSTR nodeName; nodeName = mpINode->GetName(); toolTip.printf("%s [Falloff: %5.2f]", nodeName.data(), (double) pLight->GetFallsize(t)); SetGizmoScale(dist / kRingScaleFactor); ConeAngleManipulator::SetValues(Point3(0,0,0), Point3(0,0,-1), dist, DegToRad(pLight->GetFallsize(t)), pLight->GetSpotShape() == RECT_LIGHT, pLight->GetAspect(t)); }
void SpotLightMultiplierManipulator::SetDistance(float distance) { GenLight* pLight = (GenLight*) mhTarget; TimeValue t = GetCOREInterface()->GetTime(); Matrix3 tm; tm = mpINode->GetObjectTM(GetCOREInterface()->GetTime()); Point3 pt; b = GetTargetPoint(t, pt); if (!b) return; TSTR nodeName; nodeName = mpINode->GetName(); float den = FLength(tm.GetRow(2)); float targetDist = (den!=0) ? FLength(tm.GetTrans()-pt) / den : 0.0f; float mult = 2.0 * distance / targetDist; pLight->SetIntensity(t, mult); }
//--------------------------------------------------------------- void LightExporter::exportLight( ExportNode* exportNode ) { if ( !exportNode->getIsInVisualScene() ) return; String lightId = getLightId(*exportNode); INode * iNode = exportNode->getINode(); LightObject* lightObject = (LightObject*) (iNode->GetObjectRef()); if ( !lightObject ) return; if ( mDocumentExporter->isExportedObject(ObjectIdentifier(lightObject)) ) return; mDocumentExporter->insertExportedObject(ObjectIdentifier(lightObject), exportNode); // Retrieve the target node, if we are not baking matrices. // Baked matrices must always sample the transform! ULONG ClassId = lightObject->ClassID().PartA(); bool isTargeted = !mDocumentExporter->getOptions().getBakeMatrices() && (ClassId == SPOT_LIGHT_CLASS_ID || ClassId == TDIR_LIGHT_CLASS_ID); INode* targetNode = isTargeted ? iNode->GetTarget() : 0; // some lights are not supported at all switch (ClassId) { case FSPOT_LIGHT_CLASS_ID: case SPOT_LIGHT_CLASS_ID: case DIR_LIGHT_CLASS_ID: case TDIR_LIGHT_CLASS_ID: case SKY_LIGHT_CLASS_ID_PART_A: case OMNI_LIGHT_CLASS_ID: break; default: return; } // Determine the light's type bool isSpot = false; bool isDirectional = false; bool isPoint = false; bool isSky = false; COLLADASW::Light::LightType lightType; switch (ClassId) { case FSPOT_LIGHT_CLASS_ID: case SPOT_LIGHT_CLASS_ID: lightType = COLLADASW::Light::SPOT; isSpot = true; break; case DIR_LIGHT_CLASS_ID: case TDIR_LIGHT_CLASS_ID: lightType = COLLADASW::Light::DIRECTIONAL; isDirectional = true; break; case SKY_LIGHT_CLASS_ID_PART_A: lightType = COLLADASW::Light::POINT; isSky = true; break; case OMNI_LIGHT_CLASS_ID: lightType = COLLADASW::Light::POINT; isPoint = true; break; } COLLADASW::Light * colladaLight = 0; switch ( lightType ) { case COLLADASW::Light::DIRECTIONAL: colladaLight = new COLLADASW::DirectionalLight(COLLADASW::LibraryLights::mSW, lightId, COLLADASW::Utils::checkNCName(NativeString(exportNode->getINode()->GetName()))); break; case COLLADASW::Light::POINT: colladaLight = new COLLADASW::PointLight(COLLADASW::LibraryLights::mSW, lightId, COLLADASW::Utils::checkNCName(NativeString(exportNode->getINode()->GetName()))); break; case COLLADASW::Light::SPOT: colladaLight = new COLLADASW::SpotLight(COLLADASW::LibraryLights::mSW, lightId, COLLADASW::Utils::checkNCName(NativeString(exportNode->getINode()->GetName()))); break; } // Retrieve the parameter block IParamBlock* parameters = 0; IParamBlock2* parametersSky = 0; if (isSky) parametersSky = (IParamBlock2*) lightObject->GetReference(MaxLight::PBLOCK_REF_SKY); else parameters = (IParamBlock*) lightObject->GetReference(MaxLight::PBLOCK_REF); if (!parameters && !parametersSky) { delete colladaLight; return; } if (parameters) { bool hasAnimatedColor = mAnimationExporter->addAnimatedParameter(parameters, MaxLight::PB_COLOR, lightId, colladaLight->getColorDefaultSid(), 0 ); colladaLight->setColor(EffectExporter::maxColor2Color(parameters->GetColor(MaxLight::PB_COLOR)), hasAnimatedColor); } else if (parametersSky ) { bool hasAnimatedColor = mAnimationExporter->addAnimatedParameter(parametersSky, MaxLight::PB_SKY_COLOR, lightId, colladaLight->getColorDefaultSid(), 0 ); colladaLight->setColor(EffectExporter::maxColor2Color(parametersSky->GetColor(MaxLight::PB_SKY_COLOR)), hasAnimatedColor); } if (isSpot || isPoint) { int decayFunction = parameters->GetInt(isPoint ? MaxLight::PB_DECAY : MaxLight::PB_OMNIDECAY, mDocumentExporter->getOptions().getAnimationStart()); switch (decayFunction) { case 1: colladaLight->setConstantAttenuation(0.0f); colladaLight->setLinearAttenuation(1.0f); break; case 2: colladaLight->setConstantAttenuation(0.0f); colladaLight->setQuadraticAttenuation(1.0f); break; case 0: default: colladaLight->setConstantAttenuation(1.0f); break; } } else if (isSky) { colladaLight->setConstantAttenuation(1.0f); } setExtraTechnique(colladaLight); if ( parameters ) addParamBlockAnimatedExtraParameters(LIGHT_ELEMENT, LIGHT_PARAMETERS, LIGHT_PARAMETER_COUNT, parameters, lightId); else addParamBlockAnimatedExtraParameters(SKYLIGHT_ELEMENT, SKYLIGHT_PARAMETERS, SKYLIGHT_PARAMETER_COUNT, parametersSky, lightId); // add all the information to extra tag, that are not contained in IParamBlock if (isSpot || isDirectional || isPoint) { GenLight* light = (GenLight*)(lightObject); if (!light) { delete colladaLight; return; } // Export the overshoot flag for directional lights if (isDirectional || isSpot) { addExtraChildParameter(LIGHT_ELEMENT, OVERSHOOT_PARAMETER, light->GetOvershoot() != false); } addExtraChildParameter(LIGHT_ELEMENT, DECAY_TYPE_PARAMETER, (int)light->GetDecayType()); addExtraChildParameter(LIGHT_ELEMENT, USE_NEAR_ATTENUATION_PARAMETER, (light->GetUseAttenNear() != false)); addExtraChildParameter(LIGHT_ELEMENT, USE_FAR_ATTENUATION_PARAMETER, (light->GetUseAtten() != false)); exportShadowParameters(light); if (light->GetProjector()) { Texmap* projectorMap = light->GetProjMap(); if (projectorMap) { String imageId = exportTexMap(projectorMap); if ( !imageId.empty() ) { addExtraChildParameter(LIGHT_ELEMENT, LIGHT_MAP_ELEMENT, "#" + imageId); } } } } else // isSky { Texmap *colorMap = parametersSky->GetTexmap(MaxLight::PB_SKY_COLOR_MAP, mDocumentExporter->getOptions().getAnimationStart()); String imageId = exportTexMap(colorMap); if ( !imageId.empty()) { addExtraChildParameter(SKYLIGHT_ELEMENT, SKYLIGHT_COLORMAP_ELEMENT, "#" + imageId); } } addLight(*colladaLight); delete colladaLight; }
//------------------------------ GenLight* LightImporter::createGenericLight( const COLLADAFW::Light* light ) { // ambient, spot, directional, point // Create the correctly-typed 3dsMax light object int maxLightType; COLLADAFW::Light::LightType lightType = light->getLightType(); switch (lightType) { case COLLADAFW::Light::AMBIENT_LIGHT: // Ambient lighting is global and additive, in 3dsMax, // let the DocumentImporter object handle them createAndAddAmbientLight( light ); return 0; case COLLADAFW::Light::POINT_LIGHT: maxLightType = OMNI_LIGHT; break; case COLLADAFW::Light::DIRECTIONAL_LIGHT: maxLightType = /*(isTargeted) ? TDIR_LIGHT : */DIR_LIGHT; break; case COLLADAFW::Light::SPOT_LIGHT: maxLightType = /*(isTargeted) ? TSPOT_LIGHT :*/ FSPOT_LIGHT; break; default: return 0; } GenLight* maxLight = getMaxImportInterface()->CreateLightObject(maxLightType); float targetDistance = 0.0f; targetDistance = 120.0f; // may change later on if the MAX profile value was found. maxLight->SetTDist(0, targetDistance); if (lightType == COLLADAFW::Light::DIRECTIONAL_LIGHT) { maxLight->SetOvershoot(TRUE); // may change later on if the MAX profile value was found. } // Decay rates are available, in Max, on all light types // Figure out the decay type, since Max only allows for one attenuation factor // forget about the decay being animated, COLLADA doesn't support that. int decayType = 0; if (lightType == COLLADAFW::Light::POINT_LIGHT || lightType == COLLADAFW::Light::SPOT_LIGHT) { if ( light->getConstantAttenuation() > 0 ) decayType = 0; else if ( light->getLinearAttenuation() > 0 ) decayType = 1; else decayType = 2; } maxLight->SetDecayType(decayType); if (lightType == COLLADAFW::Light::SPOT_LIGHT || lightType == COLLADAFW::Light::DIRECTIONAL_LIGHT) { // Force the spot to be a circle. Some of the light values seem to be // missing default assignation on construction and instead inherit // unknown values from previous, deleted scenes. maxLight->SetSpotShape(CIRCLE_LIGHT); // Angles are shared between spot and directional lights. double fallOffAngle = light->getFallOffAngle(); maxLight->SetHotspot(0, (float)fallOffAngle); // Max crashes when the fallsize is less or equal to the hotspot maxLight->SetFallsize(0, (float)(fallOffAngle * 1.001)); } // Common light parameters Point3 color = toMaxPoint3(light->getColor()); maxLight->SetRGBColor(0, color); // maxLight->SetIntensity(0, colladaLight->GetIntensity()); // Enable light maxLight->Enable(TRUE); maxLight->SetUseLight(TRUE); return maxLight; }
void SkeletonExporter::export_light(INode *node) { Control *c; int size_key, sf; ObjectState os; GenLight* light; struct LightState ls; float near_radius, far_radius; Point3 row; Matrix3 mat; os=node->EvalWorldState(0); if (!os.obj) return; // per sicurezza light=(GenLight*)os.obj; // controlliamo se esiste un padre INode *padre=node->GetParentNode(); if ((padre) && (strcmp(padre->GetName(), "Scene Root")!=0)) sf=strlen(padre->GetName())+1; else sf=0; light->EvalLightState(0, FOREVER, &ls); fprintf(fTXT, "Name : %s\n", node->GetName()); switch (ls.type) { case OMNI_LGT: fprintf(fTXT, "Omni light found\n"); // flag padre + nome padre + pivot + NodeTM(0) + // + colore write_chunk_header(fA3D, OMNI_LIGHT_ID, node->GetName(), 4+sf+12+48+12); if (makeRAY) write_chunk_header(fRAY, OMNI_LIGHT_ID, node->GetName(), 4+sf+12+48+12); break; case SPOT_LGT: fprintf(fTXT, "Spot light found\n"); // flag padre + nome padre + pivot + NodeTM(0) + // + colore + falloff + hotspot write_chunk_header(fA3D, SPOT_LIGHT_ID, node->GetName(), 4+sf+12+48+12+8); if (makeRAY) write_chunk_header(fRAY, SPOT_LIGHT_ID, node->GetName(), 4+sf+12+48+12+8); break; } // ----------- scrivo il padre (flag, nome) ------------------ fwrite(&sf, sizeof(int), 1, fA3D); if (sf>0) write_string0(fA3D, padre->GetName()); if (makeRAY) fwrite(&sf, sizeof(int), 1, fRAY); if (makeRAY) if (sf>0) write_string0(fRAY, padre->GetName()); // --------------- scrittura del punto di pivot ---------------- GetPivotOffset(node, &row); fprintf(fTXT, "Pivot point : %f, %f, %f\n", row.x, row.y, row.z); write_point3(&row, fA3D); if (makeRAY) write_point3(&row, fRAY); // ------------------- salviamo la NodeTM(0) --------------------- mat=node->GetNodeTM(0); row=mat.GetRow(3); fprintf(fTXT, "World position : x=%f, y=%f, z=%f\n", row.x, row.y, row.z); write_matrix(&mat, fA3D); if (makeRAY) write_matrix(&mat, fRAY); // -------------------- salviamo il colore ----------------------- fprintf(fTXT, "Color : R=%f, G=%f, B=%f\n", ls.color.r, ls.color.g, ls.color.b); fwrite(&ls.color.r, sizeof(float), 1, fA3D); fwrite(&ls.color.g, sizeof(float), 1, fA3D); fwrite(&ls.color.b, sizeof(float), 1, fA3D); if (makeRAY) fwrite(&ls.color.r, sizeof(float), 1, fRAY); if (makeRAY) fwrite(&ls.color.g, sizeof(float), 1, fRAY); if (makeRAY) fwrite(&ls.color.b, sizeof(float), 1, fRAY); // ---------------------- falloff e hotpsot ---------------------- if (ls.type == SPOT_LGT) { float hotspot = (float)(ls.hotsize*3.14159265358979323846/180.0); float falloff = (float)(ls.fallsize*3.14159265358979323846/180.0); fwrite(&hotspot, sizeof(float), 1, fA3D); if (makeRAY) fwrite(&hotspot, sizeof(float), 1, fRAY); fwrite(&falloff, sizeof(float), 1, fA3D); if (makeRAY) fwrite(&falloff, sizeof(float), 1, fRAY); } fprintf(fTXT, "Intensity : %f\n", ls.intens); // -------------- esportazione tracce di posizione --------------- c=node->GetTMController()->GetPositionController(); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=36; else if (IsBezierControl(c)) size_key=40; else size_key=16; fprintf(fTXT, "Light position track present."); write_chunk_header(fA3D, POSITION_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_point3_track(c, 1, fA3D); if (makeRAY) write_chunk_header(fRAY, POSITION_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); if (makeRAY) export_point3_track(c, 1, fRAY); } // --------------- esportazione tracce di colore ----------------- c=light->GetColorControl(); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=36; else if (IsBezierControl(c)) size_key=40; else size_key=16; fprintf(fTXT, "Light color track present."); write_chunk_header(fA3D, COLOR_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_point3_track(c, 1.0f, fA3D); if (makeRAY) write_chunk_header(fRAY, COLOR_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); if (makeRAY) export_point3_track(c, 1.0f, fRAY); } // -------------- esportazione tracce di hotspot ----------------- c=light->GetHotSpotControl(); if ((c) && (c->NumKeys()>0) && (ls.type == SPOT_LGT)) { if (IsTCBControl(c)) size_key=28; else if (IsBezierControl(c)) size_key=16; else size_key=8; fprintf(fTXT, "Light hotspot track present."); write_chunk_header(fA3D, HOTSPOT_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_float_track(c, (float)(3.14159265358979323846/180.0), fA3D); // in radianti if (makeRAY) write_chunk_header(fRAY, HOTSPOT_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); if (makeRAY) export_float_track(c, (float)(3.14159265358979323846/180.0), fRAY); // in radianti } // -------------- esportazione tracce di falloff ----------------- c=light->GetFalloffControl(); if ((c) && (c->NumKeys()>0) && (ls.type == SPOT_LGT)) { if (IsTCBControl(c)) size_key=28; else if (IsBezierControl(c)) size_key=16; else size_key=8; fprintf(fTXT, "Light falloff track present."); write_chunk_header(fA3D, FALLOFF_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_float_track(c, (float)(3.14159265358979323846/180.0), fA3D); // in radianti if (makeRAY) write_chunk_header(fRAY, FALLOFF_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); if (makeRAY) export_float_track(c, (float)(3.14159265358979323846/180.0), fRAY); // in radianti } // ------------------------- script ADL -------------------------- Mtl *materiale=node->GetMtl(); // NO far + NO near if ((!light->GetUseAttenNear()) && (!light->GetUseAtten())) { far_radius=near_radius=999999; } else // NO far + SI near if ((light->GetUseAttenNear()) && (!light->GetUseAtten())) { near_radius=light->GetAtten(0, ATTEN1_START, FOREVER); far_radius=999999; } else // SI far + NO near if ((!light->GetUseAttenNear()) && (light->GetUseAtten())) { far_radius=light->GetAtten(0, ATTEN_START, FOREVER); near_radius=far_radius; } // SI far + SI near if ((light->GetUseAttenNear()) && (light->GetUseAtten())) { near_radius=light->GetAtten(0, ATTEN1_START, FOREVER); far_radius=light->GetAtten(0, ATTEN_START, FOREVER); } if (makeADL) { fprintf(fADL, " light %c%s%c\n {\n", '"', node->GetName(), '"'); if (materiale) fprintf(fADL, " material=%c%s%c;\n", '"', materiale->GetName(), '"'); else fprintf(fADL, " material=%cNONE%c;\n", '"', '"'); //fprintf(fADL, " scale_x=%c160%c;\n", '"', '"'); //fprintf(fADL, " scale_y=%c160%c;\n", '"', '"'); //fprintf(fADL, " near_radius=%c%f%c;\n", '"', near_radius, '"'); //fprintf(fADL, " far_radius=%c%f%c;\n", '"', far_radius, '"'); switch (light->GetDecayType()) { case 0: fprintf(fADL, " attenuation0=%c1.0%c;\n", '"', '"'); fprintf(fADL, " attenuation1=%c0%c;\n", '"', '"'); fprintf(fADL, " attenuation2=%c0%c;\n", '"', '"'); break; case 1: fprintf(fADL, " attenuation0=%c0%c;\n", '"', '"'); fprintf(fADL, " attenuation1=%c1.0%c;\n", '"', '"'); fprintf(fADL, " attenuation2=%c0%c;\n", '"', '"'); break; case 2: fprintf(fADL, " attenuation0=%c0%c;\n", '"', '"'); fprintf(fADL, " attenuation1=%c0%c;\n", '"', '"'); fprintf(fADL, " attenuation2=%c1.0%c;\n", '"', '"'); break; } char range[20]; my_ftoa(far_radius, range); fprintf(fADL, " max_range=%c%s%c;\n", '"', range, '"'); fprintf(fADL, " }\n\n"); } fprintf(fTXT, "\n\n\n----------------------------------------------------\n"); }
// Build a CLight bool CExportNel::buildLight (GenLight &maxLight, NL3D::CLight& nelLight, INode& node, TimeValue time) { // Eval the light state fot this time Interval valid=NEVER; LightState ls; if (maxLight.EvalLightState(time, valid, &ls)==REF_SUCCEED) { // Set the light mode switch (maxLight.Type()) { case OMNI_LIGHT: nelLight.setMode (CLight::PointLight); break; case TSPOT_LIGHT: case FSPOT_LIGHT: nelLight.setMode (CLight::SpotLight); break; case DIR_LIGHT: case TDIR_LIGHT: nelLight.setMode (CLight::DirectionalLight); break; default: // Not initialized return false; } // *** Set the light color // Get the color CRGBA nelColor; Point3 maxColor=maxLight.GetRGBColor(time); // Mul by multiply CRGBAF nelFColor; nelFColor.R=maxColor.x; nelFColor.G=maxColor.y; nelFColor.B=maxColor.z; nelFColor.A=1.f; nelFColor*=maxLight.GetIntensity(time); nelColor=nelFColor; // Affect the ambiant color ? if (maxLight.GetAmbientOnly()) { nelLight.setAmbiant (nelColor); nelLight.setDiffuse (CRGBA (0,0,0)); nelLight.setSpecular (CRGBA (0,0,0)); } else { nelLight.setAmbiant (CRGBA (0,0,0)); // Affect the diffuse color ? if (maxLight.GetAffectDiffuse()) nelLight.setDiffuse (nelColor); else nelLight.setDiffuse (CRGBA (0,0,0)); // Affect the specular color ? if (maxLight.GetAffectSpecular()) nelLight.setSpecular (nelColor); else nelLight.setSpecular (CRGBA (0,0,0)); } // Set the light position Point3 pos=node.GetNodeTM(time).GetTrans (); CVector position; position.x=pos.x; position.y=pos.y; position.z=pos.z; // Set the position nelLight.setPosition (position); // Set the light direction CVector direction; INode* target=node.GetTarget (); if (target) { // Get the position of the target Point3 posTarget=target->GetNodeTM (time).GetTrans (); CVector positionTarget; positionTarget.x=posTarget.x; positionTarget.y=posTarget.y; positionTarget.z=posTarget.z; // Direction direction=positionTarget-position; direction.normalize (); } else // No target { // Get orientation of the source as direction CMatrix nelMatrix; convertMatrix (nelMatrix, node.GetNodeTM(time)); // Direction is -Z direction=-nelMatrix.getK(); direction.normalize (); } // Set the direction nelLight.setDirection (direction); // Set spot light information nelLight.setCutoff ((float)(NLMISC::Pi*maxLight.GetFallsize(time)/180.f/2.f)); // Compute the exponent value float angle=(float)(NLMISC::Pi*maxLight.GetHotspot(time)/(2.0*180.0)); nelLight.setupSpotExponent (angle); // *** Set attenuation if (maxLight.GetUseAtten()) { float nearAtten = maxLight.GetAtten (time, ATTEN_START); if (nearAtten == 0) nearAtten = 0.1f; nelLight.setupAttenuation (nearAtten, maxLight.GetAtten (time, ATTEN_END)); } else nelLight.setNoAttenuation (); // Initialized return true; } // Not initialized return false; }