typename ElementServantObject::ResultType ElementServantObject::execAntiSideEffect(const Handler<Heap>& heap, const AntiSideEffect& val) { AntiSideEffect anti; auto servant = this->servant(); switch(val.op){ case AntiSideEffect::EnableAnimation: anti.op = servant->animEnabled() ? AntiSideEffect::None : AntiSideEffect::DisableAnimation; servant->animEnabled(true); break; case AntiSideEffect::DisableAnimation: anti.op = !servant->animEnabled() ? AntiSideEffect::None : AntiSideEffect::EnableAnimation; servant->animEnabled(false); break; case AntiSideEffect::None: CINAMO_EXCEPTION(Exception, "[BUG] None operation is not handled.") } return Just<AntiSideEffect>(anti); }
ElementServantProvider::ElementServantProvider(const Handler<Heap>& heap, const Handler<Heaven>& heaven) :Super(heap, "ElementServant", heaven) { this->registerPureNativeClosure("element", [this](ElementServantObject* servant){ return servant->servant()->element()->donutObject(); }); this->registerReactiveNativeClosure("enableAnimation", [this](ElementServantObject* servant_){ auto servant = servant_->servant(); bool enabled = servant->animEnabled(); servant->animEnabled(true); AntiSideEffect anti; anti.op = enabled ? AntiSideEffect::None : AntiSideEffect::DisableAnimation; return std::tuple<bool,Maybe<AntiSideEffect> >(enabled, Just(anti)); }); this->registerReactiveNativeClosure("disableAnimation", [this](ElementServantObject* servant_){ auto servant = servant_->servant(); bool enabled = servant->animEnabled(); servant->animEnabled(false); AntiSideEffect anti; anti.op = !enabled ? AntiSideEffect::None : AntiSideEffect::EnableAnimation; return std::tuple<bool,Maybe<AntiSideEffect> >(enabled, Just(anti)); }); }
void FltExportVisitor::writeLightPoint(const osgSim::LightPointNode *lpn) { enum Directionality { OMNIDIRECTIONAL = 0, UNIDIRECTIONAL = 1, BIDIRECTIONAL = 2 }; enum DisplayMode { RASTER = 0, CALLIG = 1, EITHER = 2 }; enum Modes { ENABLE = 0, DISABLE = 1 }; enum Flags { NO_BACK_COLOR = 0x80000000u >> 1, CALLIGRAPHIC = 0x80000000u >> 3, REFLECTIVE = 0x80000000u >> 4, PERSPECTIVE = 0x80000000u >> 8, FLASHING = 0x80000000u >> 9, ROTATING = 0x80000000u >> 10, ROTATE_CC = 0x80000000u >> 11, VISIBLE_DAY = 0x80000000u >> 15, VISIBLE_DUSK = 0x80000000u >> 16, VISIBLE_NIGHT = 0x80000000u >> 17 }; int32 flags(NO_BACK_COLOR); if (lpn->getNumLightPoints() == 0) return; // In OSG, each LightPoint within a LightPointNode can have different appearance // parameters, but in OpenFlight, a Light Point Record contains a list of homogeneous // vertices. To be correct, we'd have to look at all LightPoints in the LightPointNode // and spew out multiple FLT records for each group that shared common appearance // parameters. Instead, we cheat: We take the first LightPoint and use its appearance // parameters for all LightPoints in the LightPointNode. const osgSim::LightPoint &lp0 = lpn->getLightPoint(0); // No really good mapping between OSG and FLT light point animations. float32 animPeriod(0.f); float32 animEnabled(0.f); float32 animPhaseDelay(0.f); if (lp0._blinkSequence != NULL) { flags |= FLASHING; animPeriod = 4.f; animEnabled = 2.f; animPhaseDelay = lp0._blinkSequence->getPhaseShift(); } // Note that true bidirectional light points are currently unsupported (they are unavailable // in OSG, so we never write them out to FLT as BIDIRECTIONAL. int32 directionality(OMNIDIRECTIONAL); float32 horizLobe(360.f); float32 vertLobe(360.f); float32 lobeRoll(0.f); const osgSim::DirectionalSector *ds = dynamic_cast<osgSim::DirectionalSector*>(lp0._sector.get()); if (ds) { directionality = UNIDIRECTIONAL; horizLobe = osg::RadiansToDegrees(ds->getHorizLobeAngle()); vertLobe = osg::RadiansToDegrees(ds->getVertLobeAngle()); lobeRoll = osg::RadiansToDegrees(ds->getLobeRollAngle()); } { // Braces req'd to invoke idHelper destructor (and potentially // write LongID record) before Push Record. const uint16 length(156); IdHelper id(*this, lpn->getName()); _records->writeInt16((int16) LIGHT_POINT_OP); _records->writeInt16(length); _records->writeID(id); _records->writeInt16(0); // Surface material code _records->writeInt16(0); // Feature ID _records->writeUInt32(~0u); // OpenFlight erronously say -1, so will assume ~0u is OK. Back color for bidirectional _records->writeInt32(EITHER); // Display mode _records->writeFloat32(lp0._intensity); // Intensity _records->writeFloat32(0.f); // Back intensity TBD _records->writeFloat32(0.f); // min defocus _records->writeFloat32(0.f); // max defocus _records->writeInt32(DISABLE); // Fading mode _records->writeInt32(DISABLE); // Fog punch mode _records->writeInt32(DISABLE); // Directional mode _records->writeInt32(0); // Range mode _records->writeFloat32(lpn->getMinPixelSize()); // min pixel size _records->writeFloat32(lpn->getMaxPixelSize()); // max pixel size _records->writeFloat32(lp0._radius * 2.f); // Actual size _records->writeFloat32(1.f); // transparent falloff pixel size _records->writeFloat32(1.f); // Transparent falloff exponent _records->writeFloat32(1.f); // Transparent falloff scalar _records->writeFloat32(0.f); // Transparent falloff clamp _records->writeFloat32(1.f); // Fog scalar _records->writeFloat32(0.f); // Reserved _records->writeFloat32(0.f); // Size difference threshold _records->writeInt32(directionality); // Directionality _records->writeFloat32(horizLobe); // Horizontal lobe angle _records->writeFloat32(vertLobe); // Vertical lobe angle _records->writeFloat32(lobeRoll); // Lobe roll angle _records->writeFloat32(0.f); // Directional falloff exponent _records->writeFloat32(0.f); // Directional ambient intensity _records->writeFloat32(animPeriod); // Animation period in seconds _records->writeFloat32(animPhaseDelay); // Animation phase delay in seconds _records->writeFloat32(animEnabled); // Animation enabled period in seconds _records->writeFloat32(1.f); // Significance _records->writeInt32(0); // Calligraphic draw order _records->writeInt32(flags); // Flags _records->writeVec3f(osg::Vec3f(0.f, 0.f, 0.f)); // Axis of rotation } { osg::ref_ptr<osg::Vec3dArray> v = new osg::Vec3dArray(lpn->getNumLightPoints()); osg::ref_ptr<osg::Vec4Array> c = new osg::Vec4Array(lpn->getNumLightPoints()); osg::ref_ptr<osg::Vec3Array> n = new osg::Vec3Array(lpn->getNumLightPoints()); osg::Vec3f normal(0.f, 0.f, 1.f); unsigned int idx; for (idx = 0; idx < lpn->getNumLightPoints(); idx++) { const osgSim::LightPoint &lp = lpn->getLightPoint(idx); (*v)[idx] = lp._position; (*c)[idx] = lp._color; const osgSim::DirectionalSector *ds = dynamic_cast<osgSim::DirectionalSector*>(lp._sector.get()); if (ds) normal = ds->getDirection(); (*n)[idx] = normal; } _vertexPalette->add((const osg::Array*)NULL, v.get(), c.get(), n.get(), NULL, true, true, false); } writeMatrix(lpn->getUserData()); writeComment(*lpn); writePush(); writeVertexList(0, lpn->getNumLightPoints()); writePop(); }