Generic animation module intended to be controlled by other PartModules.

Does not include any GUI or direct-user-interactivity; all state changes must be initiated from external sources

상속: PartModule
예제 #1
0
        public void Start()
        {
            animationControl = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimationStatusChanged);
            engineModule     = null;
            ModuleEnginesFX[] engines = part.GetComponents <ModuleEnginesFX>();
            int len = engines.Length;

            for (int i = 0; i < len; i++)
            {
                if (engines[i].engineID == engineID)
                {
                    engineModule = engines[i];
                }
            }
            if (engineModule == null)
            {
                MonoBehaviour.print("ERROR: Could not locate engine by ID: " + engineID + " for part: " + part + " for SSTUAnimateEngineHeat.  This will cause errors during gameplay.  Setting engine to first engine module (if present)");
                if (engines.Length > 0)
                {
                    engineModule = engines[0];
                }
            }
            setupEngineModuleGui();
            setupGuiFields(animationControl.getAnimationState(), engineModule.EngineIgnited);
        }
예제 #2
0
        private void init()
        {
            if (initialized)
            {
                return;
            }
            initialized = true;
            if (HighLogic.LoadedSceneIsEditor || HighLogic.LoadedSceneIsFlight)
            {
                updateCrewCapacity(inflated ? inflatedCrew : deflatedCrew);
            }
            animation = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimStateChange);
            if (animation != null)
            {
                AnimState state = inflated ? AnimState.STOPPED_END : AnimState.STOPPED_START;
                animation.setToState(state);
            }

            BaseEvent evt = Events["inflateEvent"];

            evt.guiActive = evt.guiActiveEditor = !inflated;

            evt = Events["deflateEvent"];
            evt.guiActiveEditor = inflated;
            evt.guiActive       = inflated && (HighLogic.LoadedSceneIsEditor || canDeflate);

            resourceDef = PartResourceLibrary.Instance.GetDefinition(resourceName);
            if (resourceDef == null)
            {
                MonoBehaviour.print("ERROR: Could not locate resource for name: " + resourceName + " for " + this.name);
            }
            updateRequiredMass();
        }
예제 #3
0
 public void Start()
 {
     animationControl = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimationStatusChanged);
     engineModule = (ModuleEnginesFX)part.Modules[engineModuleIndex];//unsafe, but intend it to crash if setup improperly
     setupEngineModuleGui();
     setupGuiFields(animationControl.getAnimationState(), engineModule.EngineIgnited);
 }
예제 #4
0
 public override void OnStart(PartModule.StartState state)
 {
     base.OnStart(state);
     animationControl = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimationStatusChanged);
     initializeGuiFields();
     updateGuiDataFromState(animationControl.getAnimationState());
 }
예제 #5
0
 public void Start()
 {
     animationControl = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimationStatusChanged);
     engineModule     = (ModuleEnginesFX)part.Modules[engineModuleIndex];//unsafe, but intend it to crash if setup improperly
     setupEngineModuleGui();
     setupGuiFields(animationControl.getAnimationState(), engineModule.EngineIgnited);
 }
예제 #6
0
 public void Start()
 {
     if (animationID >= 0)
     {
         animationController = SSTUAnimateControlled.locateAnimationController(part, animationID, OnAnimationStatusCallback);
     }
     updateAnimationControllerState();
 }
예제 #7
0
 public void Start()
 {
     if (!string.IsNullOrEmpty(animationID))
     {
         animationController = SSTUAnimateControlled.locateAnimationController(part, animationID, OnAnimationStatusCallback);
     }
     updateAnimationControllerState();
 }
예제 #8
0
        //Static method for use by other modules to locate a control module; reduces code duplication in animation controlling modules
        public static SSTUAnimateControlled setupAnimationController(Part part, string id, ISSTUAnimatedModule module)
        {
            SSTUAnimateControlled controller = locateAnimationController(part, id);

            if (controller != null && module != null)
            {
                controller.callbacks.AddUnique(module);
            }
            return(controller);
        }
예제 #9
0
 public void Start()
 {
     needsUpdate = true;
     if (animationID >= 0)
     {
         animationControl = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimationStateChange);
         if (animationControl != null)
         {
             onAnimationStateChange(animationControl.getAnimationState());
         }
     }
 }
예제 #10
0
 public void Start()
 {
     needsUpdate = true;
     if (!string.IsNullOrEmpty(animationID))
     {
         animationControl = SSTUAnimateControlled.setupAnimationController(part, animationID, this);
         if (animationControl != null)
         {
             onAnimationStateChange(animationControl.getAnimationState());
         }
     }
 }
 private void initializeState()
 {
     if (initialized)
     {
         return;
     }
     initialized = true;
     findTransforms();
     animationController = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimationStatusChanged);
     setupDefaultRotations();
     setPanelState(panelState);
     updateGuiData();
 }
예제 #12
0
        public void Start()
        {
            if (animationID >= 0)
            {
                animation = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimStateChanged);
            }
            updateGUI();
            ModuleDockingNode mdn = part.GetComponent <ModuleDockingNode>();

            mdn.snapOffset   = snapAngle;
            mdn.snapRotation = enableSnap;
            MonoBehaviour.print("Set docking node module to snap angle: " + snapAngle + " enabled: " + enableSnap);
        }
예제 #13
0
        public void Start()
        {
            if (!string.IsNullOrEmpty(animationID))
            {
                animation = SSTUAnimateControlled.setupAnimationController(part, animationID, this);
            }
            updateGUI();
            ModuleDockingNode mdn = part.GetComponent <ModuleDockingNode>();

            mdn.snapOffset   = snapAngle;
            mdn.snapRotation = enableSnap;
            MonoBehaviour.print("Set docking node module to snap angle: " + snapAngle + " enabled: " + enableSnap);
        }
예제 #14
0
        private void updateAnimationControl(string id, SingleModelData model, int layer)
        {
            if (string.IsNullOrEmpty(id))
            {
                return;
            }
            SSTUAnimateControlled module = SSTUAnimateControlled.locateAnimationController(part, id);

            if (module != null)
            {
                module.initializeExternal(model.getAnimationData(model.model.transform, layer));
            }
        }
예제 #15
0
 private void initializeState()
 {
     if (initialized || !moduleIsEnabled)
     {
         return;
     }
     initialized = true;
     findTransforms();
     animationController = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimationStatusChanged);
     setupDefaultRotations();
     setPanelState(panelState);
     updateGuiData();
     suncatcherAngleAxis = (Axis)Enum.Parse(typeof(Axis), sunAxis);
 }
예제 #16
0
 private void initializeState()
 {
     if (initialized || !moduleIsEnabled)
     {
         return;
     }
     initialized = true;
     findTransforms();
     animationController = SSTUAnimateControlled.setupAnimationController(part, animationID, this);
     setupDefaultRotations();
     setPanelState(panelState);
     loadPivotSaveData(persistentData);
     updateGuiData();
     suncatcherAngleAxis = (Axis)Enum.Parse(typeof(Axis), sunAxis);
 }
예제 #17
0
        private void updateSolarModules()
        {
            if (!updateSolar)
            {
                return;
            }
            if (animationControl == null)
            {
                SSTUAnimateControlled[] controls = part.GetComponents <SSTUAnimateControlled>();
                int len = controls.Length;
                for (int i = 0; i < len; i++)
                {
                    if (controls[i].animationID == solarAnimationID)
                    {
                        animationControl = controls[i]; break;
                    }
                }
            }

            animationControl.animationName = solarModule.animationName;
            animationControl.reInitialize();

            SSTUSolarPanelDeployable solar = part.GetComponent <SSTUSolarPanelDeployable>();

            if (solar == null)
            {
                return;
            }

            solar.resourceAmount           = solarModule.energy;
            solar.pivotTransforms          = solarModule.pivotNames;
            solar.secondaryPivotTransforms = solarModule.secPivotNames;
            solar.rayTransforms            = solarModule.sunNames;

            SSTUSolarPanelDeployable.Axis axis = (SSTUSolarPanelDeployable.Axis)Enum.Parse(typeof(SSTUSolarPanelDeployable.Axis), solarModule.sunAxis);
            solar.setSuncatcherAxis(axis);

            if (solarModule.panelsEnabled)
            {
                solar.enableModule();
            }
            else
            {
                solar.disableModule();
            }
        }
예제 #18
0
        public void Start()
        {
            AnimState state = AnimState.STOPPED_END;

            if (animationID >= 0)
            {
                animController = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimStateChange);
                state          = animController.getAnimationState();
            }
            bool uiEnabled = state == AnimState.STOPPED_END && !autoRotate;

            if (state == AnimState.STOPPED_END && autoRotate)
            {
                rotating = true;
            }
            updateUIControlState(uiEnabled);
        }
예제 #19
0
 public override void OnStart(PartModule.StartState state)
 {
     base.OnStart(state);
     animationControl = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimationStatusChanged);
     initializeGuiFields();
     updateGuiDataFromState(animationControl.getAnimationState());
     BaseAction deploy = Actions[nameof(deployAction)];
     if (deploy.actionGroup == KSPActionGroup.REPLACEWITHDEFAULT)
     {
         deploy.actionGroup = actionGroup;
     }
     BaseAction retract = Actions[nameof(retractAction)];
     if (retract.actionGroup == KSPActionGroup.REPLACEWITHDEFAULT)
     {
         retract.actionGroup = actionGroup;
     }
 }
예제 #20
0
        public void Start()
        {
            AnimState state = AnimState.STOPPED_END;

            if (!string.IsNullOrEmpty(animationID))
            {
                animController = SSTUAnimateControlled.setupAnimationController(part, animationID, this);
                state          = animController.getAnimationState();
            }
            bool uiEnabled = state == AnimState.STOPPED_END && !autoRotate;

            if (state == AnimState.STOPPED_END && autoRotate)
            {
                rotating = true;
            }
            updateUIControlState(uiEnabled);
        }
예제 #21
0
        public override void OnStart(PartModule.StartState state)
        {
            base.OnStart(state);
            animationControl = SSTUAnimateControlled.setupAnimationController(part, animationID, this);
            initializeGuiFields();
            updateGuiDataFromState(animationControl.getAnimationState());
            BaseAction deploy = Actions[nameof(deployAction)];

            if (deploy.actionGroup == KSPActionGroup.REPLACEWITHDEFAULT)
            {
                deploy.actionGroup = actionGroup;
            }
            BaseAction retract = Actions[nameof(retractAction)];

            if (retract.actionGroup == KSPActionGroup.REPLACEWITHDEFAULT)
            {
                retract.actionGroup = actionGroup;
            }
        }
예제 #22
0
 public void disableModule()
 {
     moduleIsEnabled = false;
     energyFlow      = 0;
     Events["extendEvent"].active    = false;
     Events["retractEvent"].active   = false;
     Fields["guiStatus"].guiActive   = false;
     Actions["toggleAction"].active  = false;
     Actions["extendAction"].active  = false;
     Actions["retractAction"].active = false;
     sunTransform       = null;
     windBreakTransform = null;
     pivotData          = null;
     suncatcherData     = null;
     if (animationController != null)
     {
         animationController.removeCallback(onAnimationStatusChanged);
     }
     animationController = null;
 }
예제 #23
0
        private void updateAnimationControl(string id, SingleModelData model, int layer)
        {
            if (string.IsNullOrEmpty(id))
            {
                return;
            }
            SSTUAnimateControlled module = SSTUAnimateControlled.locateAnimationController(part, id);

            if (module == null)
            {
                MonoBehaviour.print("ERROR: Could not locate controller for name: " + id);
                return;
            }
            else if (module != null && model.model != null)
            {
                module.initializeExternal(model.getAnimationData(model.model.transform, layer));
            }
            else if (module != null)
            {
                module.initializeExternal(new SSTUAnimData[0]);
            }
        }
예제 #24
0
        private void init()
        {
            if (initialized) { return; }
            initialized = true;
            if (HighLogic.LoadedSceneIsEditor || HighLogic.LoadedSceneIsFlight)
            {
                updateCrewCapacity(inflated ? inflatedCrew : deflatedCrew);
            }
            animation = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimStateChange);
            if (animation != null)
            {
                AnimState state = inflated ? AnimState.STOPPED_END : AnimState.STOPPED_START;
                animation.setToState(state);
            }

            BaseEvent evt = Events["inflateEvent"];
            evt.guiActive = evt.guiActiveEditor = !inflated;

            evt = Events["deflateEvent"];
            evt.guiActiveEditor = inflated;
            evt.guiActive = inflated && (HighLogic.LoadedSceneIsEditor || canDeflate);

            resourceDef = PartResourceLibrary.Instance.GetDefinition(resourceName);
            if (resourceDef == null)
            {
                MonoBehaviour.print("ERROR: Could not locate resource for name: " + resourceName + " for " + this.name);
            }
            updateRequiredMass();
        }
예제 #25
0
 public void Start()
 {
     animationControl = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimationStatusChanged);
     engineModule = null;
     ModuleEnginesFX[] engines = part.GetComponents<ModuleEnginesFX>();
     int len = engines.Length;
     for (int i = 0; i < len; i++)
     {
         if (engines[i].engineID == engineID)
         {
             engineModule = engines[i];
         }
     }
     if (engineModule == null)
     {
         MonoBehaviour.print("ERROR: Could not locate engine by ID: " + engineID + " for part: " + part + " for SSTUAnimateEngineHeat.  This will cause errors during gameplay.  Setting engine to first engine module (if present)");
         if (engines.Length > 0) { engineModule = engines[0]; }
     }
     setupEngineModuleGui();
     setupGuiFields(animationControl.getAnimationState(), engineModule.EngineIgnited);
 }
 //TODO - might need to force-disable effects (if they exist)
 //find animations, check for control enabled
 public override void OnStart(PartModule.StartState state)
 {
     if(controlID==-1){moduleControlEnabled=true;}
     animationControl = SSTUAnimateControlled.locateAnimationController (part, animationID, onAnimationStatusChanged);
     base.OnStart(state);
     if(moduleControlEnabled)
     {
         setupGuiFields(animationControl==null? SSTUAnimState.STOPPED_END : animationControl.getAnimationState(), EngineIgnited);
     }
     else//disabled engine entire, disable all events/gui stuff/staging icon
     {
         disableAllGuiFields();
         if(part.stagingIcon!=null && part.stagingIcon.Equals(DefaultIcons.LIQUID_ENGINE.ToString()))
         {
             part.stagingIcon = string.Empty;
         }
     }
 }
 private void initializeState()
 {
     if(initialized){return;}
     initialized = true;
     parseTransformData();
     findTransforms();
     animationController = SSTUAnimateControlled.locateAnimationController (part, animationID, onAnimationStatusChanged);
     setPanelState(panelState);
     updateGuiData();
 }
예제 #28
0
 public void Start()
 {
     if (animationID >= 0)
     {
         animationController = SSTUAnimateControlled.locateAnimationController(part, animationID, OnAnimationStatusCallback);
     }
     updateAnimationControllerState();
 }
예제 #29
0
        private void updateSolarModules()
        {
            if (!updateSolar)
            {
                return;
            }
            if (animationControl == null && !string.Equals("none", solarAnimationID))
            {
                SSTUAnimateControlled[] controls = part.GetComponents <SSTUAnimateControlled>();
                int len = controls.Length;
                for (int i = 0; i < len; i++)
                {
                    if (controls[i].animationID == solarAnimationID)
                    {
                        animationControl = controls[i];
                        break;
                    }
                }
                if (animationControl == null)
                {
                    MonoBehaviour.print("ERROR: Animation controller was null for ID: " + solarAnimationID);
                    return;
                }
            }

            bool   animEnabled  = solarModule.model.hasAnimation();
            bool   solarEnabled = solarModule.model.panelsEnabled;
            string animName     = string.Empty;
            float  animSpeed    = 1f;

            if (animEnabled)
            {
                ModelAnimationData mad = solarModule.model.modelDefinition.animationData[0];
                animName  = mad.animationName;
                animSpeed = mad.speed;
            }
            else
            {
                animName  = string.Empty;
                animSpeed = 1f;
            }

            if (animationControl != null)
            {
                animationControl.animationName  = animName;
                animationControl.animationSpeed = animSpeed;
                animationControl.reInitialize();
            }

            SSTUSolarPanelDeployable solar = part.GetComponent <SSTUSolarPanelDeployable>();

            if (solar != null)
            {
                if (solarEnabled)
                {
                    solar.resourceAmount  = solarModule.model.energy;
                    solar.pivotTransforms = solarModule.model.pivotNames;
                    solar.rayTransforms   = solarModule.model.sunNames;

                    SSTUSolarPanelDeployable.Axis axis = (SSTUSolarPanelDeployable.Axis)Enum.Parse(typeof(SSTUSolarPanelDeployable.Axis), solarModule.model.sunAxis);
                    solar.setSuncatcherAxis(axis);
                    solar.enableModule();
                }
                else
                {
                    solar.disableModule();
                }
            }
        }
        private void updateSolarModules()
        {
            if (!updateSolar) { return; }
            if (animationControl == null)
            {
                SSTUAnimateControlled[] controls = part.GetComponents<SSTUAnimateControlled>();
                int len = controls.Length;
                for (int i = 0; i < len; i++)
                {
                    if (controls[i].animationID == solarAnimationID) { animationControl = controls[i]; break; }
                }
            }

            animationControl.animationName = solarModule.animationName;
            animationControl.reInitialize();

            SSTUSolarPanelDeployable solar = part.GetComponent<SSTUSolarPanelDeployable>();
            if (solar == null) { return; }

            solar.resourceAmount = solarModule.energy;
            solar.pivotTransforms = solarModule.pivotNames;
            solar.secondaryPivotTransforms = solarModule.secPivotNames;
            solar.rayTransforms = solarModule.sunNames;

            SSTUSolarPanelDeployable.Axis axis = (SSTUSolarPanelDeployable.Axis)Enum.Parse(typeof(SSTUSolarPanelDeployable.Axis), solarModule.sunAxis);
            solar.setSuncatcherAxis(axis);

            if (solarModule.panelsEnabled)
            {
                solar.enableModule();
            }
            else
            {
                solar.disableModule();
            }
        }
예제 #31
0
        public override void OnStart(PartModule.StartState state)
        {
            base.OnStart (state);

            #region animationSetup
            animationController = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimationStatusChanged);
            #endregion

            #region gui setup
            Events["retractEvent"].guiName = retractGuiName;
            Events["deployEvent"].guiName = deployGuiName;
            Events["repairEvent"].guiName = repairGuiName;
            Actions["toggleAction"].guiName = actionGroupGuiName;

            Events["retractEvent"].active = legState==LegState.DEPLOYED;
            Events["deployEvent"].active = legState==LegState.RETRACTED;
            Events["repairEvent"].active = legState==LegState.BROKEN;
            #endregion

            #region colliderSetup
            if(HighLogic.LoadedSceneIsFlight)
            {
                //setup suspension upper limits, defaults to config value for suspension travel
                if(suspensionUpperLimit==-1){suspensionUpperLimit=suspensionTravel;}

                String[] wcNameArray = wheelColliderNames.Split(',');
                String[] susNameArray = suspensionTransformNames.Split(',');
                String[] footNameArray = footColliderNames.Split(',');
                int length = wcNameArray.Length < susNameArray.Length ? wcNameArray.Length : susNameArray.Length;

                LandingLegData legData;
                Transform suspensionTransform;
                Transform wheelColliderTransform;
                Transform footColliderTransform;
                WheelCollider wheelCollider;
                float wcRadius = 0, wcTravel = 0, wcTarget = 0, wcSpring = 0, wcDamper = 0;

                for(int i = 0; i < length; i++)
                {

                    suspensionTransform = part.FindModelTransform(susNameArray[i].Trim());
                    wheelColliderTransform = part.FindModelTransform(wcNameArray[i].Trim());
                    if(suspensionTransform==null || wheelColliderTransform==null)
                    {
                        print ("error locating transforms for names: "+susNameArray[i]+", "+wcNameArray[i]);
                        print ("found objects: "+suspensionTransform+", "+wheelColliderTransform);
                        continue;
                    }
                    wheelCollider = wheelColliderTransform.GetComponent<WheelCollider>();
                    if(wheelCollider==null)
                    {

                        print ("Wheel collider transform does not contain a valid wheel collider!  name: "+wcNameArray[i]);
                        SSTUUtils.recursePrintComponents(wheelColliderTransform.gameObject, "");
                        continue;
                    }
                    if(i<footNameArray.Length)
                    {
                        footColliderTransform = part.FindModelTransform(footNameArray[i].Trim ());
                    }
                    else
                    {
                        footColliderTransform = null;
                    }
                    legData = new LandingLegData();
                    legData.suspensionTransform = suspensionTransform;
                    legData.wheelCollider = wheelCollider;
                    legData.footColliderTransform = footColliderTransform;
                    this.legData.Add (legData);

                    //use default values if config values were not written
                    wcRadius = wheelColliderRadius==-1 ? wheelCollider.radius : wheelColliderRadius;
                    wcTravel = suspensionTravel==-1 ? wheelCollider.suspensionDistance : suspensionTravel;
                    wcTarget = suspensionTarget==-1 ? wheelCollider.suspensionSpring.targetPosition : suspensionTarget;
                    wcSpring = suspensionSpring==-1 ? wheelCollider.suspensionSpring.spring : suspensionSpring;
                    wcDamper = suspensionDamper==-1 ? wheelCollider.suspensionSpring.damper : suspensionDamper;

                    //setup wheel collider radius and suspension distance in case of overrides in config
                    wheelCollider.radius = wcRadius;
                    wheelCollider.suspensionDistance = wcTravel;
                    wheelCollider.brakeTorque = 1000f;

                    //setup a new JointSpring for the wheel to use, overriding values from config if needed
                    JointSpring spring = new JointSpring();
                    spring.spring = wcSpring;
                    spring.damper = wcDamper;
                    spring.targetPosition = wcTarget;
                    wheelCollider.suspensionSpring = spring;//assign the new spring joint to the wheel collider
                }
            }

            #endregion

            setLegState(legState);
            if(!moduleControlEnabled)
            {
                onControlDisabled();
            }
        }
예제 #32
0
 public void Start()
 {
     needsUpdate = true;
     if (animationID >= 0)
     {
         animationControl = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimationStateChange);
         if (animationControl != null) { onAnimationStateChange(animationControl.getAnimationState()); }
     }
 }
 public void disableModule()
 {
     moduleDisabled = true;
     energyFlow = 0;
     Events["extendEvent"].active = false;
     Events["retractEvent"].active = false;
     Fields["guiStatus"].guiActive = false;
     Actions["toggleAction"].active = false;
     Actions["extendAction"].active = false;
     Actions["retractAction"].active = false;
     sunTransform = null;
     windBreakTransform = null;
     pivotData = null;
     secondaryPivotData = null;
     suncatcherData = null;
     if (animationController != null) { animationController.removeCallback(onAnimationStatusChanged); }
     animationController = null;
 }
 public void Start()
 {
     if (animationID >= 0)
     {
         animation = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimStateChanged);
     }
     updateGUI();
     ModuleDockingNode mdn = part.GetComponent<ModuleDockingNode>();
     mdn.snapOffset = snapAngle;
     mdn.snapRotation = enableSnap;
     MonoBehaviour.print("Set docking node module to snap angle: " + snapAngle + " enabled: " + enableSnap);
 }
예제 #35
0
 public override void OnStart(PartModule.StartState state)
 {
     if (controlID == -1) { moduleControlEnabled = true; }
     base.OnStart(state);
     animationControl = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimationStatusChanged);
     initializeGuiFields();
     updateGuiDataFromState(animationControl.getAnimationState());
 }
 private void initializeState()
 {
     if (initialized) { return; }
     initialized = true;
     findTransforms();
     animationController = SSTUAnimateControlled.locateAnimationController(part, animationID, onAnimationStatusChanged);
     setupDefaultRotations();
     setPanelState(panelState);
     updateGuiData();
     suncatcherAngleAxis = (Axis)Enum.Parse(typeof(Axis), sunAxis);
 }