//---------------------------------------------------------------
	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;

	}
Пример #2
0
AWDPrimitive * MaxAWDExporter::ExportPrimitiveGeom(Object * obj, char * name){
    Class_ID classId = obj->ClassID();
    if (classId.PartA() == EDITTRIOBJ_CLASS_ID || classId.PartA() == TRIOBJ_CLASS_ID ){
        return NULL;
    }
    AWD_primitive_type isPrimitve=AWD_PRIMITIVE_UNDEFINED;
    if (classId == Class_ID( BOXOBJ_CLASS_ID, 0 ))
        isPrimitve=AWD_PRIMITIVE_CUBE;
    if (classId == Class_ID( SPHERE_CLASS_ID, 0 ))
        isPrimitve=AWD_PRIMITIVE_SPHERE;
    if (classId == Class_ID( CYLINDER_CLASS_ID, 0 ))
        isPrimitve=AWD_PRIMITIVE_CYLINDER;
    if (classId == PLANE_CLASS_ID)
        isPrimitve=AWD_PRIMITIVE_PLANE;
    if (classId == Class_ID( CONE_CLASS_ID, 0 ))
        isPrimitve=AWD_PRIMITIVE_CONE;
    if (classId == Class_ID( TORUS_CLASS_ID, 0 ))
        isPrimitve=AWD_PRIMITIVE_TORUS;
    if (classId ==PYRAMID_CLASS_ID){}
    if (classId == GSPHERE_CLASS_ID){}
    if (classId == Class_ID( TUBE_CLASS_ID, 0 )){}
    if (classId == Class_ID( HEDRA_CLASS_ID, 0 )){}
	// KBEN:
    //if (classId == Class_ID( BOOLOBJ_CLASS_ID, 0 )){}
    if (isPrimitve!=AWD_PRIMITIVE_UNDEFINED){
        AWDPrimitive *awdGeom = (AWDPrimitive *)primGeocache->Get(obj);
        if (awdGeom == NULL) {
            IParamBlock* pblk = GetParamBlockByIndex((ReferenceMaker* )obj, 0);
            if (pblk){
                if (isPrimitve==AWD_PRIMITIVE_CUBE){
                    awdGeom=new AWDPrimitive(name, strlen(name), AWD_PRIMITIVE_CUBE);
                    awdGeom->set_Yoffset(pblk->GetFloat(BOXOBJ_HEIGHT) /2);
                    awdGeom->add_number_property(PROP_PRIM_NUMBER1, pblk->GetFloat(BOXOBJ_WIDTH) * opts->Scale(), 100);
                    awdGeom->add_number_property(PROP_PRIM_NUMBER2, pblk->GetFloat(BOXOBJ_HEIGHT) * opts->Scale(), 100);
                    awdGeom->add_number_property(PROP_PRIM_NUMBER3, pblk->GetFloat(BOXOBJ_LENGTH) * opts->Scale(), 100);
                    awdGeom->add_bool_property(PROP_PRIM_BOOL1, false, true);
                    int cubeSegX=pblk->GetInt(BOXOBJ_WSEGS);
                    if(cubeSegX>100) cubeSegX=100;
                    int cubeSegY=pblk->GetInt(BOXOBJ_HSEGS);
                    if(cubeSegY>100) cubeSegY=100;
                    int cubeSegZ=pblk->GetInt(BOXOBJ_LSEGS);
                    if(cubeSegZ>100) cubeSegZ=100;
                    awdGeom->add_int_property(PROP_PRIM_INT1, cubeSegX, 1);
                    awdGeom->add_int_property(PROP_PRIM_INT2, cubeSegY, 1);
                    awdGeom->add_int_property(PROP_PRIM_INT3, cubeSegZ, 1);
                }
                if (isPrimitve==AWD_PRIMITIVE_SPHERE){
                    awdGeom=new AWDPrimitive(name, strlen(name), AWD_PRIMITIVE_SPHERE);
                    awdGeom->add_number_property(PROP_PRIM_NUMBER1, pblk->GetFloat(SPHERE_RADIUS) * opts->Scale(), 50);
                    awdGeom->add_int_property(PROP_PRIM_INT1, pblk->GetInt(SPHERE_SEGS), 24);
                    //bool sphere_smooth=pblk->GetInt(SPHERE_SMOOTH);
                    //float sphere_hemisphere=pblk->GetFloat(SPHERE_HEMI);
                    //int sphere_radius=pblk->GetInt(SPHERE_SQUASH);
                    //int sphere_radius=pblk->GetInt(SPHERE_RECENTER);
                }
                if (isPrimitve==AWD_PRIMITIVE_CYLINDER){
                    awdGeom=new AWDPrimitive(name, strlen(name), AWD_PRIMITIVE_CYLINDER);
                    awdGeom->set_Yoffset(pblk->GetFloat(CYLINDER_HEIGHT) /2);
                    awdGeom->add_number_property(PROP_PRIM_NUMBER1, pblk->GetFloat(CYLINDER_RADIUS) * opts->Scale(), 50);
                    awdGeom->add_number_property(PROP_PRIM_NUMBER2, pblk->GetFloat(CYLINDER_RADIUS) * opts->Scale(), 50);
                    awdGeom->add_number_property(PROP_PRIM_NUMBER3, pblk->GetFloat(CYLINDER_HEIGHT) * opts->Scale(), 100);
                    awdGeom->add_int_property(PROP_PRIM_INT1, pblk->GetInt(CYLINDER_SIDES), 16);
                    awdGeom->add_int_property(PROP_PRIM_INT2, pblk->GetInt(CYLINDER_SEGMENTS), 1);
                    //int cylinder_capsegments=pblk->GetInt(CYLINDER_CAPSEGMENTS);
                    //bool cylinder_slice_on=pblk->GetInt(CYLINDER_SLICEON);
                    //int box_depth_segs=pblk->GetInt(CYLINDER_SMOOTH);
                }
                if (isPrimitve==AWD_PRIMITIVE_CONE){
                    float cone_radius2=pblk->GetFloat(CONE_RADIUS2);
                    if (cone_radius2==0.0){
                        awdGeom=new AWDPrimitive(name, strlen(name), AWD_PRIMITIVE_CONE);
                        awdGeom->set_Yoffset(pblk->GetFloat(CONE_HEIGHT) /2);
                        awdGeom->add_number_property(PROP_PRIM_NUMBER1, pblk->GetFloat(CONE_RADIUS1) * opts->Scale(), 50);
                        awdGeom->add_number_property(PROP_PRIM_NUMBER2, pblk->GetFloat(CONE_HEIGHT) * opts->Scale(), 100);
                        awdGeom->add_int_property(PROP_PRIM_INT1, pblk->GetInt(CONE_SIDES), 16);
                        awdGeom->add_int_property(PROP_PRIM_INT2, pblk->GetFloat(CONE_SEGMENTS), 1);
                    }
                    else{
                        awdGeom=new AWDPrimitive(name, strlen(name), AWD_PRIMITIVE_CYLINDER);
                        awdGeom->set_Yoffset(pblk->GetFloat(CONE_HEIGHT) /2);
                        awdGeom->add_number_property(PROP_PRIM_NUMBER1, pblk->GetFloat(CONE_RADIUS2) * opts->Scale(), 50);
                        awdGeom->add_number_property(PROP_PRIM_NUMBER2, pblk->GetFloat(CONE_RADIUS1) * opts->Scale(), 50);
                        awdGeom->add_number_property(PROP_PRIM_NUMBER3, pblk->GetFloat(CONE_HEIGHT) * opts->Scale(), 100);
                        awdGeom->add_int_property(PROP_PRIM_INT1, pblk->GetInt(CONE_SIDES), 16);
                        awdGeom->add_int_property(PROP_PRIM_INT2, pblk->GetInt(CONE_SEGMENTS), 1);
                    }
                    //int cone_capSegments=pblk->GetInt(CONE_CAPSEGMENTS);
                    //int cone_smooth=pblk->GetInt(CONE_SMOOTH);
                    //int cone_slice_on=pblk->GetInt(CONE_SLICEON);
                }
                if (isPrimitve==AWD_PRIMITIVE_CAPSULE){//not in 3dsmax supported...
                    awdGeom=new AWDPrimitive(name, strlen(name), AWD_PRIMITIVE_CAPSULE);
                }
                if (isPrimitve==AWD_PRIMITIVE_TORUS){
                    awdGeom=new AWDPrimitive(name, strlen(name), AWD_PRIMITIVE_TORUS);
                    awdGeom->add_number_property(PROP_PRIM_NUMBER1, pblk->GetFloat(TORUS_RADIUS) * opts->Scale(), 10);
                    awdGeom->add_number_property(PROP_PRIM_NUMBER2, pblk->GetFloat(TORUS_RADIUS2) * opts->Scale(), 100);
                    awdGeom->add_int_property(PROP_PRIM_INT1, pblk->GetInt(TORUS_SEGMENTS), 16);
                    //float torus_rotation=pblk->GetFloat(TORUS_ROTATION);
                    //float torus_twist=pblk->GetFloat(TORUS_TWIST);
                    //int torus_sides=pblk->GetInt(TORUS_SIDES);
                    //int torus_smooth=pblk->GetInt(TORUS_SMOOTH);
                    //int torus_slice_on=pblk->GetInt(TORUS_SLICEON);
                }
                awd->add_prim_block(awdGeom);
                primGeocache->Set(obj, awdGeom);
                return awdGeom;
            }
            else {
                IParamBlock2* pblk2 = GetParamBlock2ByIndex((ReferenceMaker* )obj, 0);
                if (pblk2){
                    if (isPrimitve==AWD_PRIMITIVE_PLANE){
                        awdGeom=new AWDPrimitive(name, strlen(name), AWD_PRIMITIVE_PLANE);
                        int numBlockparams=pblk2->NumParams();
                        int p=0;
                        for (p=0; p<numBlockparams; p++) {
                            ParamID pid = pblk2->IndextoID(p);
                            ParamDef def = pblk2->GetParamDef(pid);
                            ParamType2 paramtype = pblk2->GetParameterType(pid);
                            char * paramName=W2A(def.int_name);
                            if (paramtype==TYPE_FLOAT){
                                if (ATTREQ(paramName, "length"))
                                    awdGeom->add_number_property(PROP_PRIM_NUMBER2, pblk2->GetFloat(pid) * opts->Scale(), 100);
                                if (ATTREQ(paramName, "width"))
                                    awdGeom->add_number_property(PROP_PRIM_NUMBER1, pblk2->GetFloat(pid) * opts->Scale(), 100);
                            }
                            if (paramtype==TYPE_INT){
                                if (ATTREQ(paramName, "lengthsegs"))
                                   awdGeom->add_int_property(PROP_PRIM_INT2, pblk2->GetInt(pid), 1);
                                if (ATTREQ(paramName, "widthsegs"))
                                   awdGeom->add_int_property(PROP_PRIM_INT1, pblk2->GetInt(pid), 1);
                            }
                            free(paramName);
                        }
                    }
                    awd->add_prim_block(awdGeom);
                    primGeocache->Set(obj, awdGeom);
                    return awdGeom;
                }
            }
        }
        return awdGeom;
    }
    return NULL;
}