예제 #1
0
        public bool ConnectHair(SharedWorld world, Scene scene)
        {
            Skeleton hairskel     = null;
            Skeleton bodyskel     = null;
            Scene    displayScene = world.GetScene();

            try
            {
                bodyskel = currentAvatar.BodyPoser;
                if (bodyskel == null)
                {
                    SharedWorld.LogError("MagicMirror: Cannot connect hair - avatar skeleton missing");
                    return(false);
                }
                hairskel = currentAvatar.ConnectHair(displayScene.Engines);
                if (hairskel == null)
                {
                    SharedWorld.LogError("MagicMirror: could not connect hair " + scene.Name);
                    return(false);
                }
            }
            catch (Exception ex)
            {
                SharedWorld.LogError("MagicMirror: exception connecting hair " + ex.Message);
                return(false);
            }
            return(true);
        }
예제 #2
0
        /*!
         * Plays the named animation on the current avatar.
         * The animation will not be played if it has not already been loaded.
         * @param name	name of animation to play
         * @param blend	time in seconds to blend to this animation (0 = no blending)
         *
         * @see LoadAnimation PauseAnimation
         */
        public virtual void PlayAnimation(String name, float blend)
        {
            SharedWorld world = SharedWorld.Get();

            if (nowPlaying != null)
            {
                return;
            }
            try
            {
                Group g = scriptor.Find(name + '.', Group.FIND_START | Group.FIND_CHILD);

                world.SuspendScene();
                if (g != null)
                {
                    scriptor.End();
                    nowPlaying = g as Engine;
                    scriptor.Begin(g.Name);
                }
                else
                {
                    nowPlaying = null;
                }
            }
            catch (Exception ex)
            {
                SharedWorld.LogError("PlayAnimation EXCEPTION " + ex.Message);
                nowPlaying = null;
            }
            world.ResumeScene();
        }
예제 #3
0
 protected override void OnStartup(StartupEventArgs e)
 {
     Canvas3D.UsePhysics = true;
     Canvas3D.Debug      = 1;
     VixWorld            = new SharedWorld();
     base.OnStartup(e);
 }
예제 #4
0
        public bool SaveCloth()
        {
            Model parent;
            Model tmproot;
            Model clothroot = (Model)_root.Find(BaseName + "." + BaseName, Group.FIND_EXACT | Group.FIND_DESCEND);
            bool  rc;

            if (clothroot == null)
            {
                SharedWorld.LogError("Cannot find cloth model " + BaseName + "." + BaseName);
                return(false);
            }
            parent = clothroot.Parent();
            clothroot.Remove(false);
            tmproot      = new Model();
            tmproot.Name = BaseName + ".root";
            tmproot.Append(clothroot);
            rc = SharedWorld.Get().SaveAsVix(tmproot, BaseName + ".vix");
            if (!rc)
            {
                SharedWorld.LogError("Cannot save cloth meshes " + BaseName + ".vix");
            }
            clothroot.Remove(false);
            parent.Append(clothroot);
            return(rc);
        }
예제 #5
0
        public bool SaveAnimation(MeshAnimator meshanim)
        {
            String name = AnimName;
            bool   rc;
            Engine simroot;
            Engine oldroot;

            if (meshanim == null)
            {
                return(false);
            }
            if (BaseName != null)
            {
                name += "_" + BaseName;
            }
            oldroot = meshanim.Parent();
            meshanim.Remove(false);
            simroot      = new Engine();
            simroot.Name = name + ".simroot";
            meshanim.Stop();
            meshanim.Disable(MeshAnimator.RECORD, Engine.CONTROL_CHILDREN);
            simroot.Append(meshanim);
            rc = SharedWorld.Get().SaveAsVix(simroot, name + ".vix");
            if (!rc)
            {
                SharedWorld.LogError("Cannot save cloth animations " + name + ".vix");
            }
            meshanim.Remove(false);
            oldroot.Append(meshanim);
            return(rc);
        }
예제 #6
0
        /*
         * Vixen event handler. Responds to selection events:
         *	Event.SELECT	shape picked in 3D scene
         *	Event.DESELECT	nothing picked in 3D scene
         *	Event.ENTER		3D object enters trigger area
         *	Calls the OnPick function to handle the selection.
         */
        public override void OnVixen(Event ev, SharedWorld world)
        {
            int code = ev.Code;

            if (code == Event.SELECT)
            {
                try
                {
                    PickEvent pe     = ev as PickEvent;
                    Shape     picked = pe.Target as Shape;
                    OnPick(picked);
                }
                catch (Exception) { }
            }
            else if (code == Event.ENTER)
            {
                try
                {
                    TriggerEvent te     = ev as TriggerEvent;
                    Shape        picked = te.Target as Shape;
                    OnPick(picked);
                }
                catch (Exception) { }
            }
            else if (code == Event.DESELECT)
            {
                OnPick(null);
            }
            base.OnVixen(ev, world);
        }
예제 #7
0
        public override void OnSceneLoad(SharedWorld world, Scene scene, String scenefile)
        {
            if (!sceneLoaded &&
                (cameraOutput == null) &&
                (scenefile == interiorRoot.FileName))
            {
                if (masterKinect != null)
                {
                    cameraOutput = MakeCameraOutputShape(scene.Camera, true);
                    sceneRoot.Append(cameraOutput);
                    cameraOutput.Active = true;
                    SharedWorld.Trace("Scene: " + sceneRoot.Name + " -> child " + cameraOutput.Name + "\n");
                }
                if (frontAnimTrigger != null)
                {
                    Box3 b = new Box3(-2.0f, 0.0f, -0.05f, 2.0f, 3.0f, 2.0f);

                    frontAnimTrigger.SetGeoBox(b);
                    frontAnimTrigger.Options = Trigger.BOX;
                    frontAnimTrigger.SetFlags((uint)SharedObj.DOEVENTS);
                    frontAnimTrigger.Active = true;
                }
            }
            base.OnSceneLoad(world, scene, scenefile);
        }
예제 #8
0
        protected override void OnInitialized(System.EventArgs e)
        {
            SharedWorld world;
            string      fname;

            if (scene == null)
            {
                scene = new AvatarScene();
            }
            base.OnInitialized(e);
            world = SharedWorld.Get();
            if (MediaDir == null)
            {
                MediaDir = world.GetMediaDir();
            }
            fname = world.FileName;
            if ((fname != null) && fname.ToLower().EndsWith(".json"))
            {
                ConfigOpts = LoadConfig(fname);
            }
            else if (ConfigFile != null)
            {
                ConfigOpts = LoadConfig(ConfigFile);
            }
            if (ConfigOpts.mediadir != null)
            {
                MediaDir = ConfigOpts.mediadir;
            }
            Scene.RenderOptions = ConfigOpts.render;
        }
예제 #9
0
        /*!
         * @param world	current world
         * @param scene	avatar which finished loading
         *
         * Called when an avatar has finished loading.
         * This function always invokes the LoadAvatarEvent handler.
         */
        public virtual void OnAvatarLoad(SharedWorld world, Scene scene)
        {
            Skeleton skel = ConnectAvatar(world, scene);

            if (skel == null)
            {
                return;
            }
            SharedWorld.Trace("Loaded avatar, creating closet");
            if (closet == null)
            {
                closet          = new Closet(garmentRoot, skel);
                closet.scriptor = scriptor;
            }
            if (config.interior != null)
            {
                LoadScene(Path.Combine(config.mediadir, config.interior));
            }
            if (config.closet != null)
            {
                LoadCloset(Path.Combine(config.mediadir, config.closet));
            }
            if (config.hair != null)
            {
                LoadHair(Path.Combine(config.mediadir, config.hair));
            }
            if (LoadAvatarEvent != null)
            {
                LoadAvatarEvent(currentAvatar.Name);
            }
        }
예제 #10
0
        protected override void OnStartup(StartupEventArgs e)
        {
            VixWorld = new SharedWorld();

            Canvas3D.UsePhysics = true;
            Canvas3D.StartVixen(VixWorld);
            base.OnStartup(e);
        }
예제 #11
0
        protected override void OnSceneChange(SharedWorld world, Scene scene)
        {
            bool firstTime = !sceneLoaded;

            base.OnSceneChange(world, scene);
            if (firstTime && (masterKinect != null))
            {
                masterKinect.SetFlags((uint)SharedObj.DOEVENTS);
                masterKinect.Options = (int)BodyTracker.TRACK_FRONT_ONLY | (int)BodyTracker.TRACK_SKELETON;
                world.Observe(Event.TRACK);
            }
        }
예제 #12
0
        /*!
         * Hides the named garment if it is currently draped on the avatar.
         *
         * @see ShowGarment LoadGarment
         */
        public virtual void HideGarment(String name)
        {
            Garment g = closet.Find(name);

            if (g != null)
            {
                g.Hide();
            }
            else
            {
                SharedWorld.LogError("Cannot find garment " + name);
            }
        }
예제 #13
0
        /*
         * void LoadAnimations(dynamic avatarconfig)
         * Load the mesh animations associated with this garment.
         * @param avatarconfig	"avatar" section of the config file
         *
         */
        public void LoadAnimations(dynamic avatarconfig)
        {
            dynamic anims = (this as dynamic).animation;

            char[]  delims       = { (char)'/', (char)'\\', (char)'.' };
            dynamic g            = this;
            String  garment_name = g.name;

            if (anims == null)
            {
                return;
            }
            String avatar_name = avatarconfig.rig + ".skeleton.anim";

            foreach (string s in anims)
            {
                String base_name = Path.GetFileNameWithoutExtension(s);
                String script    = "";

                if (s.IndexOfAny(delims) < 0)
                {
                    continue;
                }
                if (!base_name.EndsWith("_" + garment_name))
                {
                    throw new FileLoadException("Incorrect animation naming in closet file, animation names must end with garment name suffix", s);
                }
                String anim_name     = base_name.Substring(0, base_name.Length - garment_name.Length - 1);
                String meshanim_name = g.name + ".meshanim";
                String anim_eng_name = base_name + '.' + meshanim_name + ".anim";

                enableAnims  += "enable " + anim_eng_name + "\n";
                disableAnims += "disable " + anim_eng_name + "\n";
                if (s.EndsWith("xml"))
                {
                    Animator anim = scriptor.MakeAnim(anim_eng_name, clothMesh, false);
                    anim.SetEngineName(meshanim_name);
                    anim.SetFileName(s);
                    SharedWorld.Get().Observe(Event.LOAD_SCENE, anim);
                    AvatarScene.LoadMayaCache(g, s, null, scriptor);
                }
                else
                {
                    script += "load " + s + " " + meshanim_name + " -s  -t " + garment_name + "." + garment_name + "\n";
                }
                script += "onevent loadscene " + anim_eng_name + ", begin " + anim_eng_name + " -with " + anim_name + "." + avatar_name;
                scriptor.Exec(script);
                Console.WriteLine("LoadAnimations: " + script);
            }
        }
예제 #14
0
        protected override Skeleton ConnectAvatar(SharedWorld world, Scene scene)
        {
            Skeleton skeleton = base.ConnectAvatar(world, scene);

            if ((skeleton != null) &&
                (outfitSelector != null) &&
                (typeof(TriggerSelector).IsAssignableFrom(outfitSelector.GetType())))
            {
                TriggerSelector tmp = outfitSelector as TriggerSelector;

                tmp.AddCollider(currentAvatar.RightHand);
                tmp.AddCollider(currentAvatar.LeftHand);
            }
            return(skeleton);
        }
예제 #15
0
        /*!
         * @param ev	Vixen event to handle.
         * @param world	current world
         * Handles vixen events which come from the body tracker.
         * This function also calls event handlers for BodyTrackEvents.
         */
        public override void OnVixen(Event ev, SharedWorld world)
        {
            int code = ev.Code;

            if (code == Event.TRACK)
            {
                TrackEvent kev = (TrackEvent)ev;

                if (kev.Type == TrackEvent.NEW_USER)
                {
                    OnNewUser(kev.UserID);
                }
                else if (kev.Type == TrackEvent.START_BODY_TRACK)
                {
                    OnStartTrack(kev.UserID);
                }
                else if (kev.Type == TrackEvent.PAUSE_BODY_TRACK)
                {
                    OnPauseTrack(kev.UserID);
                }
                else if (kev.Type == TrackEvent.STOP_BODY_TRACK)
                {
                    OnStopTrack(kev.UserID);
                }
                else if (kev.Type == TrackEvent.INIT_DONE)
                {
                    OnSensorInit();
                }
                else if (kev.Type == TrackEvent.USER_TURN)
                {
                    OnUserTurn(kev.UserID, kev.Position);
                }
            }
            else if (code == Event.ENTER && enableAnimation)
            {
                try
                {
                    TriggerEvent te = ev as TriggerEvent;
                    if (te.Sender.SameAs(frontAnimTrigger))
                    {
                        RandomAnimation("front", blendtime);
                    }
                }
                catch (Exception) { }
            }

            base.OnVixen(ev, world);
        }
예제 #16
0
        protected void AddMeshAnimators(Model root, Engine simroot)
        {
            try
            {
                if (root.IsClass((uint)SerialID.VX_Shape))
                {
                    Vixen.Shape    shape = root as Vixen.Shape;
                    Vixen.Geometry geo   = shape.Geometry;

                    if ((geo != null) && (geo.GetNumVtx() > 0))
                    {
                        MeshAnimator meshanim;

                        if (simroot.IsClass((uint)SerialID.VX_MeshAnimator))
                        {
                            meshanim = simroot as MeshAnimator;
                        }
                        else
                        {
                            meshanim      = new MeshAnimator();
                            meshanim.Name = root.Name + ".meshanim";
                        }
                        meshanim.Target  = geo;
                        meshanim.Control = Engine.CONTROL_CHILDREN;
                        meshanim.TimeInc = TimeInc;
                        meshanim.Active  = false;
                        SharedWorld.Trace(meshanim.Name + " -> " + shape.Name);
                        if (simroot != meshanim)
                        {
                            simroot.Append(meshanim);
                            simroot = meshanim;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                SharedWorld.LogError(ex.Message);
            }
            root = root.First();
            while (root != null)
            {
                AddMeshAnimators(root, simroot);
                root = root.Next();
            }
        }
예제 #17
0
        public bool SaveAnimation()
        {
            String       name = AnimName;
            MeshAnimator tmp;
            bool         rc;

            if (_simroot == null)
            {
                return(false);
            }
            if (BaseName != null)
            {
                if (name != null)
                {
                    name += "_" + BaseName;
                }
                else
                {
                    name = BaseName;
                }
            }
            if (name == null)
            {
                name = "default";
            }
            tmp = _simroot.First() as MeshAnimator;
            if (tmp == null)
            {
                return(false);
            }
            _simroot.Name = name + ".simroot";
            tmp.Name      = name + "." + BaseName + ".meshanim";
            tmp.Stop();
            tmp.Disable(MeshAnimator.RECORD, Engine.CONTROL_CHILDREN);
            SetTarget(null);
            rc = SharedWorld.Get().SaveAsVix(_simroot, name + ".vix");
            if (!rc)
            {
                SharedWorld.LogError("Cannot save cloth animations " + name + ".vix");
            }
            SetTarget(_root);
            Clear();
            return(rc);
        }
예제 #18
0
 /*!
  * Pauses the currently playing animation.
  *
  * @see LoadAnimation PlayAnimation
  */
 public virtual void PauseAnimation(String name)
 {
     try
     {
         if (name == null)
         {
             scriptor.End();
         }
         else
         {
             scriptor.End(name);
         }
         nowPlaying = null;
     }
     catch (Exception ex)
     {
         SharedWorld.LogError("PauseAnimation EXCEPTION " + ex.Message);
     }
 }
예제 #19
0
        /*
         * Event.LOADSCENE handler - comes here when 3D scene loaded.
         * If a user interface scene is loaded (name contains "ui_")
         * bind the UI scene to the Selector for picking outfits.
         */
        public override void OnSceneLoad(SharedWorld world, Scene scene, String scenefile)
        {
            System.String name = scene.Name.ToLower();

            if (name.Contains("ui_"))
            {
                Model iconRoot = uiRoot.Find(".selectable", Group.FIND_DESCEND | Group.FIND_END) as Model;
                SharedWorld.Trace("Loaded " + name);
                if (iconRoot != null)
                {
                    RaiseSceneLoadEvent(name, scenefile);
                    if (outfitSelector != null)
                    {
                        outfitSelector.SetTarget(iconRoot);
                    }
                    return;
                }
            }
            base.OnSceneLoad(world, scene, scenefile);
        }
예제 #20
0
 /*!
  * @param world	current world
  * @param scene	new scene which has replaced current 3D scene
  *
  * Called when the 3D scene is replaced with completely new content.
  * If this is the first scene change, the event was generated during
  * initialization and the InitSceneEvent handler is invoked.
  * For any scene change the SetSceneEvent handler is invoked (not
  * just the first one).
  */
 protected virtual void OnSceneChange(SharedWorld world, Scene scene)
 {
     if (scene.SameAs(mainScene))
     {
         world.Observe(Event.ENTER);
         world.Observe(Event.LEAVE);
         world.Observe(Event.STOP);
         world.Observe(Event.SELECT);
         world.Observe(Event.DESELECT);
         world.Observe(Event.LOAD_TEXT);
         if (cameraController != null)
         {
             world.Observe(Event.NAVINPUT, cameraController);
             world.Observe(Event.NAVIGATE, cameraController);
             cameraController.Target = scene.Camera;
             SharedWorld.Trace("MagicMirror: " + cameraController.Name + " -> target " + scene.Camera.Name + "\n");
         }
         if (navigator != null)
         {
             world.Observe(Event.MOUSE, navigator);
             world.Observe(Event.NAVINPUT, navigator);
         }
         var a = config.avatar;
         if (a != null)
         {
             if ((a.name != null) && (a.filename != null))
             {
                 LoadAvatar(a.name, a.filename);
             }
         }
         if (InitSceneEvent != null)
         {
             InitSceneEvent();
         }
         return;
     }
     if (SetSceneEvent != null)
     {
         SetSceneEvent(scene.Name);
     }
 }
예제 #21
0
        /*!
         * Display the named garment on the avatar. This function will only display the clothing
         * if it has already been loaded.
         *
         * @see LoadGarment HideGarment
         */
        public virtual void ShowGarment(String name)
        {
            Garment g = closet.Find(name);

            if (g != null)
            {
                if (!g.IsLoaded)
                {
                    g.Load(null);
                }
                else
                {
                    g.Show();
                }
                currentGarment = g;
            }
            else
            {
                SharedWorld.LogError("Cannot find garment " + name);
            }
        }
예제 #22
0
        protected void AddMeshSource(Model srcroot, Engine dstroot)
        {
            if (srcroot == null)
            {
                return;
            }
            if (dstroot.IsClass((uint)SerialID.VX_MeshAnimator))
            {
                try
                {
                    MeshAnimator meshanim = dstroot as MeshAnimator;
                    Shape        dstshape = meshanim.Target as Shape;
                    String       name     = dstshape.Name;
                    Shape        srcshape;
                    Mesh         mesh;
                    VertexArray  verts;
                    int          p = name.IndexOf('.');

                    if (p > 0)
                    {
                        name = name.Substring(p);
                    }
                    srcshape = srcroot.Find(name, Group.FIND_DESCEND | Group.FIND_END) as Shape;
                    mesh     = srcshape.Geometry as Mesh;
                    verts    = mesh.Vertices;
                    SharedWorld.Trace(meshanim.Name + " -> " + srcshape.Name);
                    meshanim.SetSource(-1, verts);
                }
                catch (Exception ex)
                {
                    SharedWorld.LogError(ex.Message);
                }
            }
            dstroot = dstroot.First() as Engine;
            while (dstroot != null)
            {
                AddMeshSource(srcroot, dstroot);
                dstroot = dstroot.Next() as Engine;
            }
        }
예제 #23
0
 protected override void OnInitialized(System.EventArgs e)
 {
     if (KinectConfig != null)
     {
         MainWindow mainwin = (MainWindow)Parent;
         //mainwin.FullScreen(true);
         try
         {
             scene = new KioskScene(GetMediaPath(KinectConfig));
         }
         catch (System.IO.FileNotFoundException exc)
         {
             SharedWorld.LogError(exc.Message);
             scene = new KioskScene();
         }
     }
     else
     {
         scene = new KioskScene();
     }
     base.OnInitialized(e);
 }
예제 #24
0
        public Garment OnLoad(Scene scene, SharedWorld world, dynamic avatarconfig)
        {
            Garment g   = Find(scene.Name);
            dynamic tmp = g;

            if (g == null)
            {
                SharedWorld.LogError(scene.Name + " not a garment - ignoring this load event");
                return(null);
            }
            if (g.IsLoaded)
            {
                SharedWorld.LogError(scene.Name + " already loaded - ignoring this load event");
                return(g);
            }
            g.Connect(world, scene, avatarconfig);
            if ((scriptor != null) && (tmp.script != null))
            {
                scriptor.LoadScript(tmp.script);
            }
            Select(g);
            return(g);
        }
예제 #25
0
        /*!
         * Customizes the 3D user interface to the current closet.
         * The 3D UI has a 3D shape corresponding to each item that can
         * be selected. The name and texture of these shapes are
         * changed to correspond to individual garments in the closet.
         * If there are more clothes in the closet than items in the UI,
         * some clothing won't be selectable.
         *
         * The 3D art must adhere to the following structure:
         * Model			"uifile.selectable"
         *		Shape		"uifile.icon_item1"		(background)
         *			Shape	"uifile.plane_item1"	(thumbnail with texture)
         *		Shape		"uifile.icon_item2"		(background)
         *			Shape	"uifile.plane_item2"	(thumbnail with texture)
         *	...
         */
        public virtual void AttachCloset()
        {
            Model cur = UIRoot.First();

            foreach (dynamic g in Clothing)
            {
                if (cur == null)
                {
                    return;
                }
                try
                {
                    string name = cur.Name;
                    int    i    = name.IndexOf(".icon_");
                    if (i > 0)
                    {
                        Shape plane = cur.First() as Shape;
                        name     = name.Substring(0, i + 6) + g.Name;
                        cur.Name = name;
                        name     = plane.Name;
                        i        = name.IndexOf(".plane_");
                        if (i > 0)
                        {
                            plane.Name = name.Substring(0, i + 7) + g.Name;
                            Sampler sampler = plane.Appearance.GetSampler(0);
                            sampler.Texture.Load(g.IconFile);
                            SharedWorld.Trace(plane.Name + " replacing texture " + g.IconFile);
                        }
                    }
                }
                catch (Exception ex)
                {
                    SharedWorld.LogError("AttachCloset " + ex.Message);
                }
                cur = cur.Next();
            }
        }
예제 #26
0
 /*!
  * Performs selection highlighting for the 3D shape picked.
  */
 public virtual bool Select(Shape picked)
 {
     System.String name = picked.Name;
     if (selectedItem != null)                   // deselect the current item
     {                                           // by puttings it's former appearance back
         if ((picked != null) && (selectedItem.Name == name))
         {
             return(false);
         }
         SharedWorld.Trace(selectedItem.Name + " unselected\n");
         selectedItem.Appearance = selectedAppear;
         selectedItem            = null;         // now nothing is selected
         selectedAppear          = null;
     }
     selectedItem = picked;
     if (picked != null)
     {
         SharedWorld.Trace(name + " picked\n");
         selectedAppear          = selectedItem.Appearance;
         selectedItem.Appearance = Hilite;
         return(true);
     }
     return(false);
 }
예제 #27
0
 /*!
  * Pauses the currently playing animation.
  *
  * @see LoadAnimation PlayAnimation
  */
 public void PauseAnimation(string name)
 {
     try
     {
         Viewer3D viewer   = Viewer as Viewer3D;
         string   skelname = ConnectSkeleton();
         Scriptor scp      = AnimScriptor;
         if (skelname != null)
         {
             if (name != null)
             {
                 scp.End(name + skelname);
             }
             else
             {
                 scp.End(_animName);
             }
         }
     }
     catch (Exception ex)
     {
         SharedWorld.LogError("PauseAnimation EXCEPTION " + ex.Message);
     }
 }
예제 #28
0
/*
 * Reads a DAZ Studio DSF file with a pose in it and produces
 * a Vixen Pose object for this avatar's skeleton.
 * @param posename name of pose
 */
        public Pose ReadPose(System.String posename)
        {
            System.String filename = "pose/" + posename + "pose.dsf";
            Hashtable     poseinfo = new Hashtable();

            try
            {
                /*
                 * Parse the DAZ Studio pose file and extract the rotations
                 * for each bone into a hash table
                 */
                using (StreamReader posefile = new StreamReader(filename))
                {
                    System.String line;
                    Regex         pattern = new Regex("([a-zA-Z0-9]+)" + Regex.Escape(":?") + "rotation/([xyz])");

                    while ((line = posefile.ReadLine()) != null)
                    {
                        Match         match = pattern.Match(line);
                        System.String name;
                        System.String axis;

                        if (!match.Success)
                        {
                            continue;
                        }
                        name = match.Groups[1].ToString();
                        axis = match.Groups[2].ToString();
                        line = posefile.ReadLine();
                        int p = line.IndexOf("[ 0, ");
                        if (p > 0)
                        {
                            System.String s = line.Substring(p + 5);
                            float         angle;
                            Quat          rot;
                            Quat          q = null;

                            s     = s.Substring(0, s.IndexOf("]"));
                            angle = float.Parse(s);
                            if (angle == 0)
                            {
                                continue;
                            }
                            angle *= (float)Math.PI / 180.0f;
                            if (axis == "x")
                            {
                                q = new Quat(Model.XAXIS, angle);
                            }
                            else if (axis == "y")
                            {
                                q = new Quat(Model.YAXIS, angle);
                            }
                            else if (axis == "z")
                            {
                                q = new Quat(Model.ZAXIS, angle);
                            }
                            if (q == null)
                            {
                                continue;
                            }
                            if (poseinfo.Contains(name))
                            {
                                rot = poseinfo[name] as Quat;
                                rot.Mul(rot, q);
                            }
                            else
                            {
                                poseinfo.Add(name, q);
                            }
                        }
                    }
                }

                /*
                 * Convert hash table with rotations into a Pose.
                 * Map DAZ bone names into Vixen bone names.
                 */
                Pose pose = new Pose(BodyPoser);
                foreach (DictionaryEntry entry in poseinfo)
                {
                    System.String key      = entry.Key.ToString();
                    System.String bonename = key;
                    Quat          q        = entry.Value as Quat;
                    int           boneindex;

                    if (key == "abdomen")
                    {
                        bonename = "Torso";
                    }
                    else if (key == "rHand")
                    {
                        bonename = "RightWrist";
                    }
                    else if (key == "lHand")
                    {
                        bonename = "LeftWrist";
                    }
                    else if (key == "rShldr")
                    {
                        bonename = "RightShoulder";
                    }
                    else if (key == "lShldr")
                    {
                        bonename = "LeftShoulder";
                    }
                    else if (key == "rForeArm")
                    {
                        bonename = "RightElbow";
                    }
                    else if (key == "lForeArm")
                    {
                        bonename = "LeftElbow";
                    }
                    else if (key == "rShin")
                    {
                        bonename = "RightKnee";
                    }
                    else if (key == "lShin")
                    {
                        bonename = "LeftShin";
                    }
                    else if (key == "rThigh")
                    {
                        bonename = "RightHip";
                    }
                    else if (key == "lThigh")
                    {
                        bonename = "LeftHip";
                    }
                    else if (key == "lFoot")
                    {
                        bonename = "LeftAnkle";
                    }
                    else if (key == "rFoot")
                    {
                        bonename = "RightAnkle";
                    }
                    boneindex = BodyPoser.GetBoneIndex(bonename);
                    if (boneindex >= 0)
                    {
                        pose.SetLocalRotation(boneindex, q);
                        SharedWorld.Trace(bonename + " " + q.x + " " + q.y + " " + q.z + " " + q.w + "\n");
                    }
                }
                return(pose);
            }
            catch (Exception ex)
            {
                Canvas3D.LogError(ex.Message + " Cannot read pose file " + filename);
                return(null);
            }
        }
예제 #29
0
/*
 * Reads a DAZ Studio PZ2 file with a pose in it and produces
 * a Vixen Pose object for this avatar's skeleton.
 * @param posename file name containing pose
 */
        public Pose ReadPose(System.String name)
        {
            Hashtable poseinfo = new Hashtable();
            int       level    = 0;
            int       numbones = 0;
            int       offset   = -1;

            try
            {
                /*
                 * Parse the DAZ Studio pose file and extract the rotations
                 * for each bone into a hash table
                 */
                using (StreamReader posefile = new StreamReader("pose/" + name + ".pz2"))
                {
                    System.String line;
                    System.String bonename = "";
                    char[]        space    = new char[] { ' ' };
                    float         xrot     = 0;
                    float         yrot     = 0;
                    float         zrot     = 0;

                    while ((line = posefile.ReadLine().Trim()) != null)
                    {
                        string[] words = line.Split(space);
                        string   opcode;

                        if (line == "")
                        {
                            continue;
                        }
                        if (line.EndsWith("{"))             // open bracket increases nesting leve4l
                        {
                            ++level;
                            continue;
                        }
                        if (line.EndsWith("}"))             // close bracket decreases nesting level
                        {
                            --level;
                            if (level == 0)
                            {
                                break;
                            }
                            continue;
                        }
                        if (words.Length == 0)              // nothing parsed?
                        {
                            continue;
                        }
                        opcode = words[0];
                        if (words.Length < 1)               // has an argument?
                        {
                            continue;
                        }
                        if (opcode == "actor")              // found a new bone?
                        {
                            bonename = words[1];            // save the bone name
                            xrot     = 0;
                            yrot     = 0;
                            zrot     = 0;
                            ++numbones;
                        }
                        else if (opcode == "rotateX")       // X rotation coming up?
                        {
                            offset = 0;
                        }
                        else if (opcode == "rotateY")       // Y rotation coming up?
                        {
                            offset = 1;
                        }
                        else if (opcode == "rotateZ")       // Z rotation coming up?
                        {
                            offset = 2;
                        }
                        else if (opcode == "k")                  // is it a key?
                        {
                            float time  = float.Parse(words[1]); // parse the time
                            float angle = float.Parse(words[2]); // parse the rotation angle in degrees
                            Quat  q;

                            angle *= (float)Math.PI / 180;
                            switch (offset)
                            {
                            case 0: xrot = angle; break;

                            case 1: yrot = angle; break;

                            case 2:
                                zrot = angle;
                                if ((xrot == 0) && (yrot == 0) && (zrot == 0))
                                {
                                    break;
                                }
                                q = new Quat(Model.XAXIS, xrot);
                                if (yrot != 0)
                                {
                                    q *= new Quat(Model.YAXIS, yrot);
                                }
                                if (zrot != 0)
                                {
                                    q *= new Quat(Model.ZAXIS, yrot);
                                }
                                q.Normalize();
                                offset = -1;
                                if (q.IsEmpty())
                                {
                                    break;
                                }
                                if (bonename.Length > 0)                                            // save rotation for the bone
                                {
                                    poseinfo[bonename] = q;
                                    SharedWorld.Trace(bonename + " " + q.x + " " + q.y + " " + q.z + " " + q.w + "\n");
                                }
                                break;
                            }
                        }
                    }
                }
                if (numbones != BodyPoser.NumBones)
                {
                    Canvas3D.LogError(System.String.Format("Pose with {0} bones does not match skeleton with {1} bones", numbones, BodyPoser.NumBones));
                }

                /*
                 * Convert hash table with rotations into a Pose.
                 */
                Pose pose = new Pose(BodyPoser);
                foreach (DictionaryEntry entry in poseinfo)
                {
                    System.String key      = entry.Key.ToString();
                    System.String bonename = key;
                    Quat          q        = entry.Value as Quat;
                    int           boneindex;

                    boneindex = BodyPoser.GetBoneIndex(bonename);
                    if (boneindex >= 0)
                    {
                        pose.SetLocalRotation(boneindex, q);
                        SharedWorld.Trace(bonename + " " + q.x + " " + q.y + " " + q.z + " " + q.w + "\n");
                    }
                    else
                    {
                        Canvas3D.LogError("Cannot find bone " + bonename + " in skeleton ");
                    }
                }
                return(pose);
            }
            catch (Exception ex)
            {
                Canvas3D.LogError(ex.Message + " Cannot read pose file " + name);
                return(null);
            }
        }
예제 #30
0
/*
 * Reads a DAZ Studio PZ2 file with a pose in it and produces
 * a Vixen Pose object for this avatar's skeleton.
 * @param posename file name containing pose
 */
        public Pose ReadPose(System.String name)
        {
            ArrayList bones          = new ArrayList();
            ArrayList positions      = new ArrayList();
            int       level          = 0;
            int       numbones       = 0;
            Int32     numframes      = 0;
            bool      parsing_motion = false;

            System.String bonename = "";
            Pose          bindpose = BodyPoser.BindPose;
            Pose          pose = new Pose(BodyPoser);
            float         x, y, z;

            pose.Copy(bindpose);
            try
            {
                /*
                 * Parse the DAZ Studio pose file and extract the rotations
                 * for each bone into a hash table
                 */
                using (StreamReader posefile = new StreamReader("pose/" + name + ".bvh"))
                {
                    System.String line;
                    char[]        space = new char[] { ' ' };

                    while ((line = posefile.ReadLine().Trim()) != null)
                    {
                        string[] words = line.Split(space);
                        string   opcode;

                        if (line == "")
                        {
                            continue;
                        }

                        /*
                         * Parsing motion for each frame.
                         * Each line in the file contains the root joint position and rotations for all joints.
                         */
                        if (parsing_motion)
                        {
                            int nbones = 0;
                            if (words[0].StartsWith("Frame"))
                            {
                                continue;
                            }
                            x = float.Parse(words[0]);                                  // root bone position
                            y = float.Parse(words[1]);
                            z = float.Parse(words[2]);
                            pose.SetPosition(new Vec3(x, y, z));
                            for (int i = 3; i < words.Length; i += 3)
                            {
                                bonename = bones[nbones] as System.String;
                                int boneindex = BodyPoser.GetBoneIndex(bonename);

                                ++nbones;
                                if (boneindex >= 0)
                                {
                                    Quat q, b;
                                    z = float.Parse(words[i]);                                          // Z, Y, X rotation angles
                                    y = float.Parse(words[i + 1]);
                                    x = float.Parse(words[i + 2]);
                                    if ((x == 0) && (y == 0) && (z == 0))
                                    {
                                        continue;
                                    }
                                    if (true)
                                    {
                                        q  = new Quat(Model.ZAXIS, z * (float)Math.PI / 180);
                                        q *= new Quat(Model.YAXIS, x * (float)Math.PI / 180);
                                        q *= new Quat(Model.XAXIS, y * (float)Math.PI / 180);
                                    }
                                    else
                                    {
                                        q  = new Quat(Model.ZAXIS, y * (float)Math.PI / 180);
                                        q *= new Quat(Model.YAXIS, x * (float)Math.PI / 180);
                                        q *= new Quat(Model.XAXIS, z * (float)Math.PI / 180);
                                    }
                                    q.Normalize();
                                    b  = pose.GetLocalRotation(boneindex);
                                    q *= b;
                                    pose.SetLocalRotation(boneindex, q);
                                    SharedWorld.Trace(bonename + " " + q.x + " " + q.y + " " + q.z + " " + q.w + "\n");
                                }
                                else
                                {
                                    Canvas3D.LogError("Cannot find bone " + bonename + " in skeleton ");
                                }
                            }
                            break;
                        }

                        /*
                         * Parsing skeleton definition with joint names and positions.
                         */
                        else
                        {
                            if (words.Length < 1)                                           // has an argument?
                            {
                                continue;
                            }
                            opcode = words[0];
                            if ((opcode == "ROOT") ||                                           // found root bone?
                                (opcode == "JOINT"))                                            // found any bone?
                            {
                                bonename = words[1];                                            // save the bone name
                                ++numbones;
                            }
                            else if (opcode == "OFFSET")                                   // bone position
                            {
                                float xpos = float.Parse(words[1]);
                                float ypos = float.Parse(words[2]);
                                float zpos = float.Parse(words[3]);

                                if (bonename.Length > 0)                                                // save position for the bone
                                {
                                    bones.Add(bonename);
                                    positions.Add(new Vec3(xpos, ypos, zpos));
                                    SharedWorld.Trace(bonename + " " + xpos + " " + ypos + " " + zpos + "\n");
                                }
                                bonename = "";
                                continue;
                            }
                            else if (opcode == "MOTION")
                            {
                                parsing_motion = true;
                                if (numbones != BodyPoser.NumBones)
                                {
                                    Canvas3D.LogError(System.String.Format("Pose with {0} bones does not match skeleton with {1} bones", numbones, BodyPoser.NumBones));
                                }
                            }
                        }
                    }
                }
                return(pose);
            }
            catch (Exception ex)
            {
                Canvas3D.LogError(ex.Message + " Cannot read pose file " + name);
                return(null);
            }
        }