# Success Importing Animated Scene into Oculus Rift S

## Preamble

In an accompanying discussion, we have illustrated how an animated, interactive 3D scene can be largely defined via the xml-formatted language named COLLADA. After about six months of work, I decided that this development had progressed to the point where we should start seriously exploring what hardware should be acquired in order to allow us to fully view and interact with these COLLADA-based scenes. Here we explain what steps were followed as we attempted to figure out how to import such 3D scenes into the VR/AR environment offered by the Oculus Rift S.

On 25 February 2020 — just four days before the establishment of the White House Coronavirus Taskforce — I placed an order with Lenova for a Legion Y740 15" GTX Graphics laptop and an Oculus Rift S 3D virtual reality headset. The Oculus system arrived within a couple of weeks but — not surprisingly, given that it was being shipped from China — the Lenova laptop did not arrive until the end of March. Reacting with an abundance of caution regarding the spread of COVID-19, after its arrival I let the Lenova package sit in the entryway of our house for several days before opening it on 1 April.

## Lessons Learned Between 1 April & 11 April 2020

Key Steps:

1. On 4/4/2020, under the Windows app/start menu, I found a "Paint 3D" app.
1. I started the app; I clicked on the "3D Shapes" menu choice; then I "drew" a simple light-purple cube (default color). I spun it around to a viewing position where multiple surfaces were visible.
2. I clicked "Menu" (upper-left corner of app window) then chose "save as ... 3D model"; this saved as a ".glb" formatted file only 3K big.
3. I then copied this file into the "Oculus Home\_Import\ExampleUGC" folder.
4. I climbed back into the Oculus Rift S AR room and was able to see/grab this newly created "Paint 3D" model. YEAH!!!
5. Later this same day, using the same "Paint 3D" app, I created and successfully imported to the Oculus Rift S a yellow torus.
2.  Mac Preview of Try06.GREAT.dae
3. On 4/4/2020, I attempted to convert Try06.GREAT.dae to a "glb"-formatted file named Try06.glb. When I load this ".dae" (i.e., COLLADA) file into the Mac's Preview application, an image appears like the one shown here, on the right; the model also displays one simple animation component, namely, the largest cube spins slowly about an axis that runs through the center of the cube. (See the related comment in §VI.D, below.)
1. I used an online web-based conversion tool to handle this .dae --> .glb conversion. It is the "glTF Converter" presented by "BlackThread.io". After performing the conversion, this "tool" gave me a couple of warning messages...
1. Animation transform type "rotate" not yet implemented;
2. Use MeshStandardMaterial or MeshBasicMaterial for best results
2. Despite the warnings, I decided to move the ".glb" file into the Lenovo directory that is used for Oculus model importing. I then activated the Rift S headgear (about 10:15 pm CDT) and, sure enough, it showed my COLLADA-created model in the inventory window!!! I was able to grab this model and drop it into my "Home" AR scene. Once I grabbed the model, Oculus posted a warning that suggested I pay attention to and correct errors that were encountered during the step of dae --> glb conversion; it also put a dashed-red box around my model with a red circle/exclamation mark. So ... something needs to be fixed, but at least I proved that the entire process of placing COLLADA-based models into the AR environment ultimately should work out. GREAT!!!
4. On 4/5/2020, I edited the COLLADA file, Try06.GREAT.dae, removing the lines of xml-formatted code that activate and control the cube's animation; this modified file was stored as Try06C.dae. I used BlackThread's web-based glTF Converter to convert this edited .dae file to a .glb format. This time, I was able to import the model into the Oculus Rift S, grab it, and place it into my Oculus Home environment. TREMENDOUS success!
Notes that Joel Recorded Over the Period 1 - 11 April 2020
```01 April 2020
-- opened Lenovo box and began various setup steps
lenovo.com
microsoft (in connection with windows 10 operating system)
McAfee
Dropbox
Already had accounts established at all of these; it was mostly a matter
of finding the userid information and updating passwords.
-- Adobe:  Along with the Lenovo order, I paid for 1-year use of a large suite of Adobe
tools.  I was able to successfully send the relevant key code to Adobe, so it
-- Dropbox:  I successfully mounted Dropbox on the Lenovo/Windows10 system.

EUREKA!! I was able to point Photoshop to a sample .dae file inside Dropbox.  It
opened the file immediately and noticed that it was a 3D scene.  Then, with no
complications, it opened the 3D scene.  The colors/transparency values were darker
than they had been on the Mac/Preview app, but otherwise no complaints!

--------------------------------------------------------------------------------------------
02 April 2020
-- From my Mac desktop, I established a "Lenova" folder in Dropbox and copied
half-a-dozen already-developed .dae files into that folder.  The plan is to pull
from this set of files from the Lenovo side of things in order to more thoroughly
test and get familiar with photoshop's handling of these files.

-- Lenovo notified me that it needs to update the BIOS of my system.  It recommended
that I save the existing BIOS state before performing this update, so I have
been poking around to see where Windows10 stores this BIOS information.
"Setup will install Lenovo BIOS Update Utility into C:\BIOS\BVCN12WW

=======================
https://store.hp.com/us/en/tech-takes/how-to-reset-bios-settings-on-windows-pcs
=======================
https://windowsreport.com/flash-bios-windows-10/

For the line-command window, type "Command Prompt" or "cmd" or ... "Run" then "cmd".

Also: Press "Windows Key + X" to open Win + X menu.  Choose "Command Prompt (Admin)";
then, enter "wmic bios get smbiosbiosversion" and press "enter";

SMBIOSBIOSVersion
BVCN11WW(V1.07)
----------------------------
or, enter "systeminfo" and press "enter";  ANSWER on Lenovo:

Host Name:                 LAPTOP-36EUPT5N
OS Name:                   Microsoft Windows 10 Home
OS Version:                10.0.18362 N/A Build 18362
OS Manufacturer:           Microsoft Corporation
OS Configuration:          Standalone Workstation
OS Build Type:             Multiprocessor Free
Registered Owner:          joeltohline@gmail.com
Registered Organization:   N/A
Product ID:                00325-81656-19754-AAOEM
Original Install Date:     4/2/2020, 6:49:57 AM
System Boot Time:          4/1/2020, 6:23:16 PM
System Manufacturer:       LENOVO
System Model:              81UF
System Type:               x64-based PC
Processor(s):              1 Processor(s) Installed.
[01]: Intel64 Family 6 Model 158 Stepping 10 GenuineIntel ~2592 Mhz
BIOS Version:              LENOVO BVCN11WW(V1.07), 7/4/2019
[Joel successfully updated to V1.08 on 4/2/2020]
[Joel successfully updated Firmware as well on 4/2/2020]
Windows Directory:         C:\Windows
System Directory:          C:\Windows\system32
Boot Device:               \Device\HarddiskVolume1
System Locale:             en-us;English (United States)
Input Locale:              en-us;English (United States)
Time Zone:                 (UTC-06:00) Central Time (US & Canada)
Total Physical Memory:     16,303 MB
Available Physical Memory: 8,965 MB
Virtual Memory: Max Size:  19,247 MB
Virtual Memory: Available: 9,861 MB
Virtual Memory: In Use:    9,386 MB
Page File Location(s):     C:\pagefile.sys
Domain:                    WORKGROUP
Logon Server:              \\LAPTOP-36EUPT5N
Hotfix(s):                 6 Hotfix(s) Installed.
[01]: KB4537572
[02]: KB4497727
[03]: KB4506933
[04]: KB4537759
[05]: KB4541338
[06]: KB4551762
Network Card(s):           3 NIC(s) Installed.
[01]: Killer(R) Wireless-AC 1550i Wireless Network Adapter (9560NGW) 160MHz
Connection Name: Wi-Fi
DHCP Enabled:    Yes
DHCP Server:     192.168.0.1
[01]: 192.168.0.37
[02]: fe80::1907:dc1e:d957:9d70
[03]: 2600:8807:100:40:915e:ec3f:bf47:822e
[04]: 2600:8807:100:40:1907:dc1e:d957:9d70
[02]: Realtek PCIe GbE Family Controller
Connection Name: Ethernet
Status:          Media disconnected
[03]: Bluetooth Device (Personal Area Network)
Connection Name: Bluetooth Network Connection
Status:          Media disconnected
Hyper-V Requirements:      VM Monitor Mode Extensions: Yes
Virtualization Enabled In Firmware: Yes
Data Execution Prevention Available: Yes
=======================================

Also successfully plugged "gaming mouse" into Lenovo laptop.

--------------------------------------------------------------------------------------------
03 April 2020

-- Intalling Adobe "Dimension" in order to see if it can read .dae files.
Evidently it cannot read .dae files.

-- Noticed that a "3D Viewer" app now exists in the Windows 10 startup menu.
But, on the Lenovo, it does not recognize .dae files.

=========
-- Successfully installed Oculus Rift

ocul.us/riftsupport

Installed software should be located in ...
C:\Program Files\Oculus\

C:\Program Files\Oculus\Software

-- Plugged in (1) Mini DisplayPort connector; and (2) USB
-- Updated firmware on goggles
-- Inserted batteries into handsets
-- Update Firmware on handsets (controllers)

Oculus/Devices/Rift S ==>
-- Serial Number:  (see notes)
-- Firmware Version:  2.2.0

-- Successfully completed Oculus Rift S Tutorial; it is "WALL*E" robot game that Quang
(Kevin's work colleague) introduced me to over a year ago.

-- Also downloaded and installed "Oculus Medium"; evidently this was part of my originally
purchased Rift S package, because the button said "purchased".

-- Used Photoshop to store 3D "hologram" file in glb format ...
Then figured out where to import the file into the Rift S model store ...
I needed to store the file in ... PC\Documents\Oculus Home\_Import\ExampleUGC

I noticed that two model files (placed there by the Oculus team) already existed in
this folder and I was able to find both models under "Imported Models" on the Oculus
Rift side.  This was very useful as a starting point for understanding what I was
**supposed** to be able to do.

Oculus Rift S actually found my "hologram" file (and a separate "Cube" that I loaded),
but it was unable to execute the file and therefore I could not place these objects into
my "Home" scene.  It was nevertheless encouraging that the Oculus "app" actually
found both files.

-- https://www.oreilly.com/library/view/photoshop-cc-the/9781491905593/ch21s06.html
"Photoshop CC:  The Missing Manual, 2nd Edition by Lesa Snider"
(1) Choose 3D --> Export 3D Layer
(2) Choose one of these file formats:  Collada DAE, Flash 3D, Google Earth 4KMZ, STL, or OBJ.
--------------------------------------------------------------------------------------------
04 April 2020

-- It appears as though I should disconnect the Oculus Rift S system from the Lenovo PC
before I put the PC to sleep (e.g, before I close the laptop).  Then, when reattaching
the Rift's pair of cords, I should plug in the USB connection and wait about 5 seconds
before attaching the "video monitor" cord.  You can see connection confirmations within
the Oculus app ... go to the "DEVICES" menu item.

EUREKA!!   Under the Windows app/start menu, I found a "Paint 3D" app.
-- I started the app; I clicked on the "3D Shapes" menu choice; then I "drew" a simple
light-purple cube (default color).  I spun it around to a viewing position
where multiple surfaces were visible.
-- I clicked "Menu" (upper-left corner of app window) then chose "save as ... 3D model";
this saved as a ".glb" formatted file only 3K big.
-- I then copied this file into the "Oculus Home\_Import\ExampleUGC" folder.
-- I climbed back into the Oculus Rift S AR room and was able to see/grab this newly
created 3D model.  YEAH!!!

CAUTION:  I tried to repeat the "EUREKA!!" moment, this time drawing a yellow torus.
But, for some reason, when I enter the AR environment, even though the purple "CubeFirst"
object is still available, it does not offer the torus to me.  I notice that it also
does not recognize the (BAD) photoshopped object.

OK!!  The "Import" window worked again after I did two things: (1) Closed the Oculus app,
then reopened it; (2) Took the detailed file-name specification (.glb) off of windows
folder/file system.  Not sure which was the culprit ... probably #1.

EUREKA!!!  Successfully coverted Try06.GREAT.dae to "glb"-formatted file named Try06.glb
-- Well .... actually, this was only partially successful, but the successful aspect
was TERRIFIC!

-- Instead of asking Photoshop to do the dae --> glb conversion, I used an online web-based
conversion tool.  It is a "glTF Converter" presented by "BlackThread.io".

After performing the conversion, this "tool" gave me a couple of warning messages...
(1) Animation transform type "rotate" not yet implemented;
(2) Use MeshStandardMaterial or MeshBasicMaterial for best results

-- Despite the warnings, I decided to move the "glb" file into the Lenovo directory
that is used for Oculus model importing.  I then activated the Rift S headgear
(about 10:15 pm CDT) and, sure enough, it showed my COLLADA-created model in the
inventory window!!!!  I was able to grab this model and drop it into my "Home"
AR scene.  Once I grabbed the model, Oculus posted a warning that suggested I
pay attention to and correct errors that were encountered during the step of
dae --> glb conversion; it also put a dashed-red box around my model with a
red circle/exclamation mark.  So ... something needs to be fixed, but at least
I proved that the entire process of placing COLLADA-based models into the AR
environment ultimately should work out.  GREAT!!!

--------------------------------------------------------------------------------------------
05 April 2020

CONTINUED SUCCESS:
-- This morning I went to my Mac Pro and opened up the "Try06.GREAT.dae" file inside
the Preview app in order to prove that I was handling the appropriate .dae file.

Then I edited the file, deleting only the "library_animations" section of the
XML-based COLLADA code; I looked at the file in Preview to acknowledge that the
edits did not harm the code. I stored the edited file -- now, named "Try06C.dae" --
in a new Dropbox folder named, Dropbox\Lenovo\BlackThread.

Still on my Mac Pro, I next got into Safari and located the BlackThread.io
website.  I found the "glTF Converter" app by clicking on the (additional menu) icon
in the upper-right-hand corner of the site's home page.  I dragged-and-dropped the
"Try06C.dae" file onto the "Upload or Drop Files Here" button; the file was
automatically converted into a "glb-formatted" file.  As before, a few lines of
Warning messages appeared, but this time they **did not** include an animation
transform warning; they were only MeshMaterial warnings.

I downloaded the file by clicking on the "Export as GLB (21kb)" button; I then
moved the "Try06C.glb" file into the Dropbox\Lenovo\BlackThread folder.

-- Then I moved to my Lenovo laptop, opened up the relevant Dropbox folder, made a
copy of "Try06C.glb" file, then pasted the file into the "Oculus Home\_Import\ExampleUGC"
folder.

I put on the Rift S goggles and, sure enough, I was able to "grab" and play with
the new object from the Oculus imported inventory page.  YES!!!!

While playing with the new object, I figured out what handset buttons needed to
be clicked/held in order to "scale" (e.g., shrink or expand) the object.  This,
of course, worked on other objects as well.

NOTE:  I learned from this that the COLLADA file can contain instructions that rotate
as well as scale and translate each item in a scene but, apparently, if the file
contains any animation instructions, the BlackThread converter will complain.

-- Made model "Try08" available as imported inventory; it is basically the same as
Try06, except the larger, tilted cube is colored red while all other smaller
cubes are purple.  Oculus was able to load this ".glb" file without complaint.

-- Cut all animations out of "TL15.lagrange.dae" and got rid of planes that slice
the Type 1 ellipsoid into various octants (these were not previously active
anyway).  Then used BlackThread.io to convert it into a .glb file; it had
no complaints, aside from the same "BasicMaterials" issues already encountered.
When I "grabbed" this object in the Rift S environment, it warned me that there
was an error in the translation to glTF (.glb) -- [it also put a dashed-red box
around my model with a red circle/exclamation mark] --  but it nevertheless loaded
the basic elements of the Type 1 ellipsoid **and** the clock on the wall.  The
parameter labels were not complete/readable (also true of the image shown after
the BlackThread.io conversion) but this is a relatively minor issue, for now.

INTERESTINGLY ... in Oculus, the purple ellipsoid was hugh!!  After grabbing it,
I was able to manually shrink its overall scale.  Thereafter, is was fun to move
around, rotate, and examine the generated 3D structures -- even though the
complaining red circle/exclamation mark was always in tow.

--------------------------------------------------------------------------------------------
06 April 2020

This morning I went back to my Mac Pro to simplify even further the TL15.lagrange.dae
file.  I kept the purple ellipsoid, its spin axis, the grey "equatorial plane" frame, and
the clock-on-the-wall.  But I deleted all the parameter specifications and all of the
yellow boxes that outlined 2 of the 3 lagrange-particle orbits.  I kept the yellow
cube markers for **one** of the orbits.  I named this file, "TL15lagrangeC.dae".
Then I "dropped" this file into the BlackThread.io glTF converter and it created the
converted file named, "TL15lagrangeC.glb".

On the Lenovo PC, I put a copy of this new ".glb" file into the Oculus "ExampleUGC"
folder, then I donned the headset and was able to grab this new inventory item.  Oculus
complained in the same way as yesterday evening; in particular, the purple ellipsoid
was hugh!  But, again, I was able to manually shrink the entire object field to a
manageable size and add it to the set of objects in my Home AR environment.

================

On the Mac Pro, I edited the "TL15" file again.  This time I simply added one new,
all-encompassing "node" to the visual_scene and assigned an overall scaling of 0.05
(in all 3 dimensions) to this node.  I named the file, "TL15lagrangeD.dae"; used
the glTF converter to create the ".glb" equivalent file; and, on the Lenova PC,
put a copy of the file into the Oculus "ExampleUGC" folder.  When I donned the
headset and "grabbed" this new file from the inventory shelf, it was indeed a much
more manageable size.  Of course, the Oculus still complained about improper coding
in the .glb file.

================

I have discovered that a unique "id" must be assigned to each "node" in a visual_scene.
This is why the yellow orbit markers were not showing up in the conversion from .dae
to .glb (glTF).  This change was made, and now the model named "TL15lagrangeF" properly
displays all of the "yellow cube" markers for one lagrangian particle orbit in the
Type 1 Riemann ellipsoid.  Hurray!

This edit did not fix everything, however, as Oculus still complains that there is
something wrong with the .glb file.   I'll keep looking ...

=================

Worked for a while, editing COLLADA file and converting it to .glb (using BlackThread
and/or PhotoShop) in order to try to figure out what Oculus doesn't like.

Finally, I stripped the .dae model down to just the purple ellipsoid and I was
able to import it into Oculus without complaint.  The name of this file is...
TL15lagrangeIshort.dae (and .glb).   I guess, now, I am going to step backwards and
see when the glitch appears (or, really, no longer appears).

--------------------------------------------------------------------------------------------
07 April 2020

Starting from TL15lagrangeIshort.dae, I tried adding the yellow Lagrangian markers
back into the (otherwise only) purple ellipsoid scene.  This was not successful, as
even the Mac Pro's Preview app crashed, time after time.

TL15Kshort.dae (and .glb) --
So ... I instead tried to add just the "equatorial plane" picture frame.  This **did**
work. I successfully imported the "TL15Kshort.glb" model into the Oculus Rift S home!

For the first time, while I was wearing the Rift S headset and standing in my VR/AR
home room, I took one color photo that shows how I had placed a variety of my homemade
objects in the room; I then turned the camera around and took my first selfie.  Fun!!
By default Oculus stores these camera shots in ...
This PC\Documents\Oculus Home\Camera

In order to delete an imported object, try the following (using Google, I retrieved
this advice from forums.oculusvr.com/Home/Community/Oculus Medium ...
(1) Make sure the particular model is not placed in one of my worlds;
(2) In the inventory, bring up the Details menu by pressing B;
(3) Click the button that says "Remove Upload"

TL15Mshort.dae (and .glb) --
In this model I have added the green spin axis ... in addition to the purple ellipsoid,
and the grey midplane frame.
the green spin axis.

TL15Nshort.dae (and .glb) --
Added one, and only one, yellow (cube) marker.
Rift S has a problem loading this model, but it may be the spin axis and **not**
the marker.  Who knows?

What's wrong with .glb files in Oculus?
-- One thought is that Oculus does not like for two separate pieces of a scene to
intersect each other.  This will happen when the spin axis is added (as in TL15Mshort.dae)
**and** it will happen when a lagrangian marker is added (as in TL15Nshort.dae) to the
scene.
As a test, I went back to TL15Mshort, in which the green spin axis had been added, and
I adjusted the position + length of the axis so that it no longer insects the purple
ellipsoid.  The new output file was named "TL15M2short.dae" (and .glb).  This did not fix
the problem; hence my "thought" cannot be the problem.

--------------------------------------------------------------------------------------------
08 April 2020

RESCALING PROPERLY ...
Tried rescaling object by setting meter="0.0254" up front, and simultaneously deleting
earlier (successful) step of inserting an overarching "ZERO" node in the final scene.
Doing this in a file named, "[New]TL15K2short.dae (and .glb)".

This worked!  In the future I should set all scenes up in such a way that the overall
scaling is done by establishing this early definition to "meter".

Went back to TL15Mshort and tried the following:
-- implement proper rescaling, as described above, but leave in SpinAxis; --> TL15M3short
-- also get rid of "level ONE" nodes in visual_scene (since they are really only needed
when implementing animation) and leave in Spin Axis; --> TL15M4short
-- comment out Spin Axis. --> TL15M5short

Result is that Oculus Rift S is only happy with the last (TL15M5short) model.  This tells
me that proper rescaling + getting rid of "level ONE" nodes is okay, but there is still
something wrong with the SpinAxis.   What the heck is it???

FOUND A HINT ...
I kept the various pieces of "SpinAxis" alive, but inside the <visual_scenes> step, I told
the SpinAxis instance to refer to the "Equatorial Plane" geometry instead of the "Cylinder"
geometry.  (I also changed the scaling of the "SpinAxis" scene so that it would look
more like a frame than a stick.)  This file is TL15M7short.dae (and .glb).

This worked inside the Oculus Rift S system!!!  Yeah!

This tells me that there is a funny bug inside of the "geometry" specification of the
Cylinder.

For a while this evening I have tried to find a bug in the geometry specification of the
Cylinder, but have not  found any.  Hmmmmm.  Tomorrow, focus on the "Markers" scene
and, in particular, avoid using the <matrix> notation.

--------------------------------------------------------------------------------------------
09 April 2020

WORKING MARKER
-- I started the day by making a clone of TL15M7short.dae --> TL15P1.dae.  I then added
all of the components that were necessary to draw one yellow Lagrangian marker.

I placed only a single marker into the visual_scene; following the decisions that were
made months ago, when I was originally detailing the orbits of Lagrangian particles
in Type I Riemann ellipsoids, it was necessary to insert this Marker node in such a way
that it was a sub-node of the primary, "ellipsoid02" node.

-- Then I cloned TL15P1.dae --> TL15P2.dae.  All I changed, here, was to replace the
<matrix> command with an explicit specification of <scale> and <translate>.

-- I used BlackThread to create .glb versions of both TL15P1 and TL15P2, then imported
both objects into the Oculus Rift S.  Surprisingly (pleasantly), **both** objects
were loaded without complaints.  So ... (1) By re-introducing all of the Markers
components into the overall COLLADA code, I somehow cleared up the problem that I
was previously having with this model; and (2) I have demonstrated that it is okay
to continue specifying scale/translate instructions via the more compact, <matrix>
command.

ALL 30 MARKERS ...
-- In a new file named "TL15P1many.dae" I inserted an additional 29 markers to define
orbit #a.  Based on the result, immediately above, I have kept all <matrix>
instructions in place.

IT WORKS !!!!

ALL THREE ORBITS
-- Now I have successfully set up Lagrangian fluid markers on three separate orbits,
each with 28 - 30 markers.  I have imported this "scene" into my Oculus Home without
any errors/complaints.  The file is TL15P3many.dae (and .glb).

<lines> ... I spent some time today trying to figure out what is wrong with the "SpinAxis"
instance, which relies on my own designed "Cylinder" geometry.  Never could find
an obvious mistake.   Then, in reading back through some pages of the hardcover book
on COLLADA (2006 by Arnaud & Barnes) that I purchased several months ago, I noticed
that in addition to <triangle> and <polygon> structures, COLLADA also defines a
<lines> command.  From the sketchy example in the book, I was unable to figure out
how to insert this command into my model.

Fortunately, Google pointed me to a github site where I could see a more complete
example of a <lines> command.  Following this example, I was able to successfully
use the <lines> command to insert a (very thin) z-axis into my TL15 model; the
model file is "TL15P3line.dae".  Confirmation of success came via the Mac's Preview
app.  Tomorrow I will load this file into the Oculus Rift S to make sure that it
works there as well.

I tried, in vein, to figure out how I might **thicken** the line that is drawn by
COLLADA's <lines> command.  (Evidently there is no option for line thickness.)  But
while looking at online COLLADA documentation, I was reminded that the COLLADA
design group -- the Khronos Group -- supplies a tool to convert from COLLADA's
xml-based file format to the glTF format.  It is called "COLLADA2gltf".  Tomorrow
I will see whether this application works as well as the BlackThread glTF Converter.

COLLADA2GLTF-bin evidently generates a .glb file, which I would prefer.

--------------------------------------------------------------------------------------------
10 April 2020

I downloaded and installed the Mac version of this converter app on my Mac Pro.  I

From the BlackThread folder, I copied "Tl15P3many.dae" into the same folder where
the executable has been stored.  I then typed ...
The excution happened without complaint, and it put the resulting file under ...
output/Tl15P3many.gltf

I then made a clone of the .dae file, naming it "TL15P3test01.dae", and typed ...
The execution happened without complaint, and it put the resulting file under ...
output/TL15P3test01.glb

So I **should** have a functioning .glb file that I can import into the Oculus Rift S.

NEW OCULUS RESULT:
I put two new .glb models into the Oculus import/example folder...
(1) As explained immediately above, I used COLLADA2GLTF-bin to create
TL15P3test01.glb (no <lines> instruction).
(2) I used BlackThread to create TL15P3line.glb (includes <lines> instruction;

The file with <lines> command completely bombed in Oculus!  On the inventory shelf,
the relevant cube was red through-and-through **and** it displayed the warning
exclamation mark (!).
*******************

Poking around thru Google, it appears as
though the <lines> command is ignored (not
activated) in various COLLADA display tools,
such as Blender (for efficency reasons) and
PhotoShop.

*******************

But the "...test01.glb" trial was a success!  Without any complaints, Oculus

Hence, while the <lines> command seems not to be working (except on the Mac),
the first test of COLLADA2GLTF-bin was a success!!  Yeah!!!!

--------------------------------------------------------------------------------------------
11 April 2020

TRANSPARENCY:
I stumbled on a web site that shows a variety of (lighting) effects that can be specified
in COLLADA.  It involves a <phong> rather than <lambert> specification; and in addition
to <diffuse> lighting -- which I have been using almost exclusively and which **appears**
to let you specify 4 color values (RBGA) but which seems to work only in the Mac Preview
app -- it shows how to specify a <transparency> value with a single floating-point value
(alpha).

This <phong><transparency> setting appears to work in (1) the Mac Preview app; (2) the
BlackThread glTF (glb) converter; and (3) the Oculus Rift S.  The relevant test file
carries the name "Try04_alpha.dae" (and .glb).  HOORAY!!!

I also tried adding this transparency specification to the file named Cube/Simplest/
Try06.GREAT.dae.  This is a relatively simple example of ANIMATION.  The BlackThread
converstion to .glb seemed to work without complaint, but I was unable to import the
model into the Oculus Rift S.  (On the import "shelf", I was able to see that the
transparency level had been incorporated properly, but the "red warning box" appeared
when I tried to grab the object off of the shelf.)  I blame this on the attempt to load
a file containing animation, rather than blaming it on transparency.

Next, let's convert these same two files to .glb using the KhronosGroup (KG) conversion
routine.  Will the animation work by taking this route to the Oculus Rift S?

FANTASTIC !!!!!
Using the KG's COLLADA2GLTF, the animation actually works perfectly!!

```

1. Continuing on 4/5/2020 …
1. I similarly edited the COLLADA file, Try08.dae — a snapshot is displayed below — removing the lines of xml-formatted code that activate and control the large red cube's animation. I used BlackThread's web-based glTF Converter to convert this edited .dae file to a .glb format. I was immediately able to add this Try08.glb model to the Oculus Rift S inventory; I grabbed it and placed it into my Oculus Home environment without complaint.

It was at this time that I figured out what Oculus handset buttons need to be clicked/held in order to "scale" (e.g., shrink or expand) an object after it is placed in my Oculus Home.

2. I also cut all animations out of "TL15lagrange.dae", which is a fairly complex model that illustrates one "Type I" Riemann ellipsoid. (See the Mac Preview image, immediately below.) I used the BlackThread glTF Converter and imported it into the Oculus Rift S. But when I donned the goggles and "grabbed" this object , Oculus warned me that there was an error in the translation to glTF (.glb); it also put a dashed-red box around my model with a red circle/exclamation mark. Clearly additional work was required.

Nevertheless it was exciting to see that the basic elements of the complex, Type I ellipsoid **and** key elements of the clock on the wall made it through the .dae --> .glb conversion step.

 Mac Preview of Try08.dae Mac Preview of TL15lagrangeA.dae
3. OVERALL SCALING …

Interestingly, inside the Oculus the purple ellipsoid was hugh!! (I have seen comments by others online who have had similar experiences with odd scalings after transporting a model from one visualization tool to another.) After grabbing this purple-ellipsoid model/scene, I was able to manually shrink its overall scale. Thereafter, it was fun to shift the position, fly around, and examine the generated 3D structures — even though the complaining red circle/exclamation mark was always in tow.

Fixing the overall scaling of a model turned out to be straightforward. Each COLLADA file must include an <asset> specification; customarily this set of instructions is placed very near the top of the code. Initially, one element within the <asset> specification of my "TL15" model was <unit name="meter" meter="1"/>. After I changed this to <unit name="inch" meter="0.0254"/>, the model's scale was quite reasonable when it was re-imported into the my Oculus Home.

2. Other Small Successes
1.  First Photo in Oculus Home First Selfie

On 4/7/2020, while standing in my Oculus Home room, for the first time I used the built-in "camera" capability of the Oculus in order to take a photograph that shows some of the objects that I successfully placed in the room. I also realized that I could take a selfie! (Oculus stored both of these photos as jpg images in "This PC\Documents\Oculus Home\Camera".) After I climbed out of the Oculus Rift S environment, I was able to print these images and show them to my family. Fun!

2. On 4/9/2020, I figured out how to use COLLADA's <lines> command in order to draw a thin, uncolored Z-axis through the purple ellipsoid of my "TL15" model scene. I was motivated to experiment with this command because the green, cylindrical, pointed stick that I had built to serve as a SpinAxis seemed to be causing problems when I used BlackThread's glTF Converter. The thin line segment that was generated by the <lines> command was properly viewable by the Mac's Preview application and within the Converter routine, but it was never visible in the Oculus Rift S. [Abandoned, for now!]
3. On 4/11/2020, I discovered a second way to specify transparency (the "alpha" in RGBA) in a COLLADA lighting scheme. It involves a <phong> rather than <lambert> specification; and in addition to <diffuse> lighting — which I previously had been using almost exclusively and which **appears** to let you specify 4 color values (RGBA) but which seems to work only in the Mac Preview app — we can specify a <transparency> with a single floating-point value (alpha).
1. On 4/9/2020, near the end of the day, I was reminded that the COLLADA design group — the Khronos Group (KG) — supplies a tool to convert from COLLADA's xml-based file format to the glTF format. This application is called "COLLADA2GLTF".
2. On 4/10/2020, I downloaded and installed KG's COLLADA2GLTF on my Mac Pro. I made a clone of the COLLADA model named, "Tl15P3many.dae", calling the clone, "TL15P3test01.dae". On the Mac's command line, I then typed the instruction,

The execution happened without complaint, and the output file was written under ... output/TL15P3test01.glb.

3. Then, without any complaints, Oculus imported/loaded this .glb model perfectly. Yeah!! Moving forward, this Khronos Group conversion routine will be our application of choice.
4. On 4/11/2020, I tried adding the new transparency specification (see §V.C, above) to the COLLADA file named Cube/Simplest/Try06.GREAT.dae. This is the relatively simple example model discussed above (see §II) that includes a small amount of animation. I used the KG's COLLADA2GLTF routine to convert from .dae to .glb; then I donned the Oculus Rift S goggles and was able to import the model into my Oculus Home room without complaint. To my (ecstatic) surprise, shortly after I placed this model in my Oculus Home room, the large cube started to spin! What a terrific result! I had accomplished my primary goal of building a COLLADA model, by hand from scratch, and importing it — along with its animation element — into a high-quality VR environment!

CAUTION: In my Oculus Home environment, the large cube in the "Try06.GREAT" scene was spinning about one of the principal axes that run through the center of the cube, but it was a different principal axis than the one that I selected to use when I designed and wrote the animation section of the COLLADA code. I suspect that this happens because, within the <asset> declaration of the COLLADA code, I specify <up_axis>Z_UP</up_axis>, whereas the Oculus VR environment may default to the specification, <up_axis>Y_UP</up_axis>. This issue needs to be resolved.

## Subsequent Trials

Now, let's try to figure out how to get the various pieces of animation to behave properly inside one of the complex Riemann ellipsoid models.

### Model b41c385_DI

The primary elements of this "DI" scene — a "direct" Riemann model as viewed from the "inertial" frame of reference — are (1) the purple ellisoid; (2) a stubby black "cylinder" affixed to the (+X) end of the ellipsoid, as a reference pointer; (3) the grey equatorial (mid-plane) frame; and (4) a clock on the wall with a red "minute" hand and a black "hour" hand.

• DImod04.dae on 18 April 2020:
I had difficulty importing the ".glb" version of this file into the Oculus Rift S. I fought with the system for quite a while, thinking that for some reason the Oculus was not recognizing that I had placed a new file in the Lenovo's _Import directory. Finally, I decided that the problem was with the .glb file itself; that is, even though I was able to "Preview" the .dae file on the Mac, perhaps the Oculus was not importing the file because it was not properly formatted and/or I actually had messed up the underlying COLLADA (.dae) file.
I went back to the previous model file — that is, model DImod03.dae — and made a new COLLADA file named DImod05.dae.
• DImod05.dae on 19 April 2020:
I was able to import the .glb version of this file into the Oculus Rift S. Displaying only the "northern" half of the Riemann ellipsoid, that is, pieces labeled id="ellippsoid02" and id="ellipsoid01". The purple ellipsoid did not spin; both hands of the clock are initially pointing in the +X direction, whereas they should be pointing somewhere in the plane that is perpendicular to the X axis; the "minute" hand does not appear to be moving, but the cock-eyed "hour" hand **is** slowly turning.
• DImod06.dae on 19 April 2020:
Deleted most of the COLLADA text that specified animations and specified the visual_scene, leaving only the (northern half of the) purple ellipsoid and its black reference pointer. In the Mac's Preview app, the ellipsoid could spin properly, but when the model was loaded into the Oculus Rift S, it did not spin.
• DImod07.dae on 19 April 2020:
Deleted more lines of code — getting rid of the black reference pointer **and** tying spin to only one octant of the ellipsoid, for example — trimming the animations and visual_scene down to the point where the code closely matches Try06_Zup01.dae. In the Mac's Preview app, the ellipsoid could spin properly, but when the model was loaded into the Oculus Rift S, it did not spin.

### Model Try06

Let's approach this from the opposite direction. We'll start with the relatively simple "Try06" model — whose animated component (the large purple cube) works inside my Oculus Home — and replace the large purple block with the more sophisticated Riemann ellipsoid geometry pulled from DImod07.dae.

•  Mac Preview of Try06_Zup03.dae

Try06_Zup01.dae on 19 April 2020:

Let's use this as the base model, since it definitely works in my Oculus Home.
• Try06_Zup02.dae on 19 April 2020:
Inserted …
1. <effect id="DiffuseRed_EFE">
2. <material id="ID6_EFE" name="material"> which references DiffuseRed_EFE
3. <library_nodes><node id="ID3_EFE" name="cube_component"> which references ID6_EFE **and** "#SimpleCube" geometry
4. <visual_scene> inside <node id="Third">, replaced last line to read, <instance_node url="#ID3_EFE" />
• Try06_Zup03.dae on 19 April 2020:     Mac Preview image of this model shown here, on the right -->
1. <library_nodes><node id="ID3_EFE" name="cube_component"> replaced referenced geometry with "#EllipsoidOctant" geometry
2. Inserted 2555 lines of code that defines <geometry id="EllipsoidOctant">

THIS WORKS!!     Inside my Oculus Rift S Home, the single red octant starts out a bit tilted (as did the large cube), then it spins about its (longest) x-axis. Note, however, that when we open this .dae file inside the Mac Preview app, it spins about the (shortest) z-axis. Why is this?

• Try06_Xup03.dae and Try06_Yup03.dae on 20 April 2020:
Both of these new COLLADA files are identical to Try06_Zup03.dae except inside the <asset> specification, Z_UP has been changed to X_UP and Y_UP, respectively. When these new files were imported into the Oculus Rift S, the layout of the purple blocks and relative position/orientation of the red ellipsoid octant was identical to the Z_UP model. The only thing that changed was the orientation of the coordinate system — e.g., the white circular hoop defining the equatorial plane — that is used by the Oculus hand-controllers. This all makes logical sense, but it is still unclear why the animation specified inside the COLLADA file leads in all three cases to a red ellipsoid octant that is spinning about the model's z-axis.
• Try06_ZupXrot04.dae on 20 April 2020:
A couple of changes have been made in the COLLADA file in an attempt to make the ellipsoid octant spin about a different axis inside the Oculus Rift S.
1. At the end of <animation>, changed the target from "Third/rotationZ.ANGLE" to "Third/rotationX.ANGLE"
2. <visual_scene> inside <node id="Third">, changed initial value of the "rotationX" angle from 10.0 to 0.0

As a result, the Mac Preview app **did** make the ellipsoid octant spin about the (longest) x-axis instead of the (shortest) z-axis, but after the .glb file equivalent was imported into the Oculus Rift S, nothing changed, that is, the ellipsoid octant spun, as before, about the (longest) x-axis. NOTE: When viewed using the Mac Preview app, the ellipsoid octant spins in the opposite direction to the spin viewed inside the Oculus Rift S.

• Try06_ZupXrot05.dae on 20 April 2020:
A few minor alterations …
1. Set start and end animation times to 0.0 and 20.0, respectively;
2. Set "end" value of angle to -135 degrees;
3. Inside the "Third" node of <visual_scene>, commented out the sid="rotationY" and sid="rotationZ" declarations.

Inside the Oculus Rift S home, the initial orientation of the ellipsoid octant remained as before, but this time it spun in the opposite direction [as desired/intended] and it seemed to be interpreting the unit of time as one second.

•  Zup Zrot06 target="Third/RotationZ.ANGLE" [0 --> -135] rotation X, Y, Z = 0.0, 0.0, 180.0

Try06_ZupZrot06.dae on 20 April 2020:
A couple of seemingly minor alterations …

1. Assigned a unique "name" to each node under <library_nodes>;
2. Inside the "Third" node of <visual_scene>, retained all 3 "sid" rotations, but assigned a nonzero (180°) ANGLE value to (only) the sid="rotationZ" declaration.

WORKS!    This time, inside the Oculus Rift S home, the ellipsoid octant spun about the Z-axis, as desired.

• Try06_ZupZrot07.dae on 20 April 2020:
Changed starting ANGLE of rotationZ from 180° to 45°
RESULT: Apparently Oculus does not pay attention to the starting angle for the axis (e.g., rotationZ) of rotation that is being animated.
• Try06_ZupYrot07.dae on 20 April 2020:
Trying to animate "rotationY" instead of "rotationZ", starting from rotationY = 45°
RESULT: This is the first time that Oculus correctly depicts rotation about the intermediate (Y) axis.
•  Zup Yrot08 target="Third/RotationY.ANGLE" [90 --> -45] rotation X, Y, Z = 90.0, 10.0, 0.0

Try06_ZupYrot08.dae on 20 April 2020:
NEXT …

1. Try inserting a different starting angle inside the "animation" specification of starting and ending ANGLEs; specifically told it to run "rotationY" from +90° to -45°
2. Try spinning about the Y-axis after initially reorienting the X-axis; specifically set initial values of rotationX = 90; rotationY = 10; rotationZ = 0

RESULT: It looks as though it **did** initially spin about the x-axis by 90° and it looks like it spun about the Z(!) axis from 90° to -45°. Why did it spin about the Z-axis instead of about the Y-axis? Perhaps it will shift to the Y-axis if I set rotationY = 0.0 (instead of 10.0) initially.
WAIT …    The observed behavior inside Oculus makes sense because after the ellipsoid octant is initially spun about the X-axis by 90°, the body frame's Y-axis is pointing straight up, in the direction of the original Z-axis. So, spinning about the (new) Y-axis looks as though the object is spinning about its original Z-axis. Yeah!!

•  Zup Zrot10 target="Third/RotationY.ANGLE" [0 --> +135] rotation X, Y, Z = 180.0, 90.0, 45.0

Try06_ZupZrot10.dae on 21 April 2020:
NEXT …

SUMMARY:

• If the animation targets rotation about the Z-axis (Y-axis), then the 3D visualization algorithm ignores the initially assigned [static] value of the rotationZ (rotationY) ANGLE.
• It definitely matters in which order the rotations are implemented. For example, inside the <node id="Third"> specification the rotations are executed from the top, down; if they are listed in the order … rotationX, rotationY, rotationZ … and the animation is about the Z-axis, then the initial setup executes rotationX before rotationY and it ignores rotationZ. However, if they are listed in the order … rotationY, rotationX, rotationZ … and the animation is about the Z-axis, then the initial setup executes rotationY before rotationX and it ignores rotationZ.

### Full Ellipsoid

 Mac Preview of FullEllip02.dae

Here we attempt to put together all eight octants to form a "full" ellipsoid that is spinning about a common (Z) axis. We begin by making a copy of "Try06_ZupZrot10.dae" and name the new file, "FullEllip01.dae". Next, we make a temporary copy of the "b41c385_DI.dae" model and cut everything away except the <geometry id="ReflectOctant">. We concatenate this geometry element with the "FullEllip01.dae" model file, inserting the concatenated portion into the <library_geometries> segment of the COLLADA code. The only additional step was to insert the "#ReflectOctant" instance into the <library_nodes> element that has id="ID3_EFE", along with the already existing "#EllipsoidOctant" instance.

• FullEllip02.dae on 21 April 2020:
The image presented here on the right shows what the resulting configuration looked like in the Mac Preview app. After the code executed the instructions rotationX = 180 and rotationY = 90, as desired (see the above-tabulated values for the "parent" COLLADA file, "Zup Zrot10"), the Z-axis of this ellipsoid quadrant points out of the page toward the viewer. Fortunately, the conversion from .dae to .glb format, as well as the import into the Oculus Rift S went very smoothly. It worked the first time in both venues; in particular, when animated, this red ellipsoid quadrant spun counter-clockwise about the (newly oriented) Z-axis, moving from 0° to +135°, as intended.
• FullEllip04.dae on 21 April 2020:
Leaving the "First" quadrant of the ellipsoidal configuration in its original orientation (with the X-axis parallel to the line of purple cubes), this is an attempt to "replicate and flip" this First quadrant three times in such a way that the entire ellipsoidal surface is fully visualized, then spin all four quadrants in sync about the (original) ± Z-axis. Initially we set up four separate nodes in the <visual_scene> such that …
• id="First" Quadrant: rotation(X,Y,Z) = (0.0, 0.0, 0.0)
• id="Second" Quadrant: rotation(X,Y,Z) = (180.0, 0.0, 0.0)
• id="Third" Quadrant: rotation(X,Y,Z) = (0.0, 180.0, 0.0)
• id="Fourth" Quadrant: rotation(X,Y,Z) = (180.0, 180.0, 0.0)
```                <node id="First" name="First_instance_EFE">^M
<translate>0.0 5.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0  0.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  0.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  0.0</rotate>^M
<scale sid="scale">3.0 3.0 3.0</scale>^M
<instance_node url="#ID3_EFE" />^M
</node>^M
<node id="Second" name="Second_instance_EFE">^M
<translate>0.0 5.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0  180.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0    0.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0    0.0</rotate>^M
<scale sid="scale">3.0 3.0 3.0</scale>^M
<instance_node url="#ID3_EFE" />^M
</node>^M
<node id="Third" name="Third_instance_EFE">^M
<translate>0.0 5.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0    0.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  180.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0    0.0</rotate>^M
<scale sid="scale">3.0 3.0 3.0</scale>^M
<instance_node url="#ID3_EFE" />^M
</node>^M
<node id="Fourth" name="Fourth_instance_EFE">^M
<translate>0.0 5.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0  180.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  180.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0    0.0</rotate>^M
<scale sid="scale">3.0 3.0 3.0</scale>^M
<instance_node url="#ID3_EFE" />^M
</node>^M
```

And we basically cloned the original animation element to create a pair of instructions …

• <animation id="First_rotation_euler_Z">: Spins from 0° to +135° and is channeled to (1) target="First/rotationZ.ANGLE", and (2) target="Fourth/rotationZ.ANGLE".
• <animation id="Cube_rotation_euler_Z">: Spins from 0° to -135° and is channeled to (1) target="Second/rotationZ.ANGLE", and (2) target="Third/rotationZ.ANGLE".
```    <channel source="#First_rotation_euler_Z-sampler" target="First/rotationZ.ANGLE"/>
<channel source="#First_rotation_euler_Z-sampler" target="Fourth/rotationZ.ANGLE"/>
```
```    <channel source="#Cube_rotation_euler_Z-sampler" target="Third/rotationZ.ANGLE"/>^M
<channel source="#Cube_rotation_euler_Z-sampler" target="Second/rotationZ.ANGLE"/>^M```

This COLLADA model worked perfectly, as desired, when I loaded it into the Mac Pro's Preview app. But the animation was funky when viewed with the Oculus Rift S. All four quadrants were initially aligned, covering the entire ellipsoidal surface as desired; and the initial orientation of the ellipsoid was correct. But the four quadrants spun about the longest (X) axis rather than about the shortest (Z) axis. I wonder what is causing this!

• FullAgain05.dae on 22 April 2020 [also, FullAgain22.dae on 23 April 2020]:
Inside the <visual_scene id="ID1">, we enclosed the First-thru-Fourth nodes inside of an overarching parent node with id="EntireEllipsoid" as follows …
```          <node id="EntireEllipsoid" name="OculusRift_EFE">
<translate>0.0 8.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0  0.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  0.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  0.0</rotate>^M
<scale sid="scale">4.0 4.0 4.0</scale>^M
<node id="First" name="First_instance_EFE">^M
<translate>0.0 0.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0  0.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  0.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  0.0</rotate>^M
<scale sid="scale">1.0 1.0 1.0</scale>^M
<instance_node url="#ID3_EFE" />^M
</node>^M
<node id="Second" name="Second_instance_EFE">^M
<translate>0.0 0.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0  180.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0    0.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0    0.0</rotate>^M
<scale sid="scale">1.0 1.0 1.0</scale>^M
<instance_node url="#ID3_EFE" />^M
</node>^M
<node id="Third" name="Third_instance_EFE">^M
<translate>0.0 0.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0    0.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  180.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0    0.0</rotate>^M
<scale sid="scale">1.0 1.0 1.0</scale>^M
<instance_node url="#ID3_EFE" />^M
</node>^M
<node id="Fourth" name="Fourth_instance_EFE">^M
<translate>0.0 0.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0  180.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  180.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0    0.0</rotate>^M
<scale sid="scale">1.0 1.0 1.0</scale>^M
<instance_node url="#ID3_EFE" />^M
</node>^M
</node>^M
```

Notice that the scaling and translation instructions now reside inside the overarching "EntireEllipsoid" node. And, consistent with this node rearrangement, the animation instruction is reduced to a single "channel" …

```    <channel source="#First_rotation_euler_Z-sampler" target="EntireEllipsoid/rotationZ.ANGLE"/>^M
```

This all worked fine, except inside the Oculus Rift S environment, the ellipsoid spins about the longest (X) axis of the object, rather than about the shortest (Z) axis, as desired and as is the case when viewed with the Mac's Preview app. Hmmmm!

• FullAgain06.dae on 22 April 2020:
Scaled the "First" quadrant node by (1.1, 1.1, 1.1) in order for it to stick out a bit from the other quadrants to help me decipher rotational behavior; and reoriented the "EntireEllipsoid" initially by turning it 90° in X and 90° in Y. But the animation instructions were not altered.
```          <node id="EntireEllipsoid" name="OculusRift_EFE">
<translate>0.0 8.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0  90.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  90.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  0.0</rotate>^M
<scale sid="scale">4.0 4.0 4.0</scale>^M
<node id="First" name="First_instance_EFE">^M
<translate>0.0 0.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0  0.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  0.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  0.0</rotate>^M
<scale sid="scale">1.1 1.1 1.1</scale>^M
<instance_node url="#ID3_EFE" />^M
</node>^M
...
```

The initial reorientation of the ellipsoid, and the "First" quadrant rescaling were both correctly implemented by both the Mac's Preview app and the Oculus Rift S environment. Also, both visualization tools continued to execute the same spin animation; in particular, inside my Oculus home the resulting spin was about the [newly oriented] longest (X) axis, as before.

 Mac Preview of FullAgain11.dae
• FullAgain11.dae on 22 April 2020:
Here the animation is directed to spin about the X-axis …
```    <channel source="#First_rotation_euler_Z-sampler" target="EntireEllipsoid/rotationX.ANGLE"/>^M
```

after reorienting the "EntireEllipsoid" initially by turning it 90° in Y and 90° in Z …

```          <node id="EntireEllipsoid" name="OculusRift_EFE">
<translate>0.0 8.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0  0.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  90.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  90.0</rotate>^M
<scale sid="scale">4.0 4.0 4.0</scale>^M
<node id="First" name="First_instance_EFE">^M
<translate>0.0 0.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0  0.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  0.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  0.0</rotate>^M
<scale sid="scale">1.1 1.1 1.1</scale>^M
<instance_node url="#ID3_EFE" />^M
</node>^M
...
```

As desired, the result in both the Oculus Home environment and in the Mac Pro Preview app — see the image immediately above — is that initially the ellipsoid is reoriented so that the shortest axis of the ellipsoid is aligned with the global X-axis, then the animation spins the ellipsoid about that (its) shortest axis.

• FullAgain30.dae on 23 April 2020: Main revision is to force rotationZ to start at a nonzero angle (here, 45°)
RESULT: WORKS!  In the sense that the Oculus animation matches that of the Mac Preview app
```      <float_array id="First_rotation_euler_Z-output-array" count="    2">^M
45.0^M
180.0^M
</float_array>^M
```
```    <channel source="#First_rotation_euler_Z-sampler" target="EntireEllipsoid/rotationZ.ANGLE"/>^M
```
```          <node id="EntireEllipsoid" name="OculusRift_EFE">
<translate>0.0 8.0 0.0</translate>^M
<rotate sid="rotationX">0.0 0.0 1.0  0.0</rotate>^M
<rotate sid="rotationY">0.0 0.0 1.0  0.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  45.0</rotate>^M
<scale sid="scale">4.0 4.0 4.0</scale>^M
<node id="First" name="First_instance_EFE">^M
<translate>0.0 0.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0  0.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  0.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  0.0</rotate>^M
<scale sid="scale">1.1 1.1 1.1</scale>^M
<instance_node url="#ID3_EFE" />^M
</node>^M
...
```
• FullAgain31.dae on 23 April 2020:   Here, all we did was set the initial "rotate Z" instruction back from 45° to 0°, which essentially matches the instructions found in FullAgain05.dae (see above)
RESULT: Oculus animation does not match Mac Preview app.
```      <float_array id="First_rotation_euler_Z-output-array" count="    2">^M
45.0^M
180.0^M
</float_array>^M
```
```    <channel source="#First_rotation_euler_Z-sampler" target="EntireEllipsoid/rotationZ.ANGLE"/>^M
```
```          <node id="EntireEllipsoid" name="OculusRift_EFE">
<translate>0.0 8.0 0.0</translate>^M
<rotate sid="rotationX">0.0 0.0 1.0  0.0</rotate>^M
<rotate sid="rotationY">0.0 0.0 1.0  0.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  0.0</rotate>^M
<scale sid="scale">4.0 4.0 4.0</scale>^M
<node id="First" name="First_instance_EFE">^M
<translate>0.0 0.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0  0.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  0.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  0.0</rotate>^M
<scale sid="scale">1.1 1.1 1.1</scale>^M
<instance_node url="#ID3_EFE" />^M
</node>^M
...
```
• FullAgain34y.dae on 23 April 2020:
RESULT: WORKS!  In the sense that the Oculus animation matches that of the Mac Preview app
```    <channel source="#First_rotation_euler_Y-sampler" target="EntireEllipsoid/rotationY.ANGLE"/>^M
```
```          <node id="EntireEllipsoid" name="OculusRift_EFE">
<translate>0.0 8.0 0.0</translate>^M
<rotate sid="rotationY">0.0 1.0 0.0  45.0</rotate>^M
<rotate sid="rotationX">1.0 0.0 0.0  0.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  0.0</rotate>^M
<scale sid="scale">4.0 4.0 4.0</scale>^M
...
```
• FullAgain36z.dae on 23 April 2020:
RESULT: WORKS!  In the sense that the Oculus animation matches that of the Mac Preview app
```    <channel source="#First_rotation_euler_Y-sampler" target="EntireEllipsoid/rotationZ.ANGLE"/>^M
```
```          <node id="EntireEllipsoid" name="OculusRift_EFE">
<translate>0.0 8.0 0.0</translate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  45.0</rotate>^M
<rotate sid="rotationX">1.0 0.0 0.0  0.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  30.0</rotate>^M
<scale sid="scale">4.0 4.0 4.0</scale>^M
...
```
• FullAgain39z.dae on 24 April 2020: (very similar to 36z)
RESULT: WORKS!  In the sense that the Oculus animation matches that of the Mac Preview app
```    <channel source="#First_rotation_euler_Y-sampler" target="EntireEllipsoid/rotationZ.ANGLE"/>^M
```
```          <node id="EntireEllipsoid" name="OculusRift_EFE">
<translate>0.0 8.0 0.0</translate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  45.0</rotate>^M
<rotate sid="rotationX">1.0 0.0 0.0  5.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  5.0</rotate>^M
<scale sid="scale">4.0 4.0 4.0</scale>^M
...
```
• FullAgain40z.dae on 24 April 2020: (very similar to 36z)
RESULT: WORKS!  In the sense that the Oculus animation matches that of the Mac Preview app
```    <channel source="#First_rotation_euler_Y-sampler" target="EntireEllipsoid/rotationZ.ANGLE"/>^M
```
```          <node id="EntireEllipsoid" name="OculusRift_EFE">
<translate>0.0 8.0 0.0</translate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  45.0</rotate>^M
<rotate sid="rotationX">1.0 0.0 0.0  90.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  0.0</rotate>^M
<scale sid="scale">4.0 4.0 4.0</scale>^M
...
```
• FullAgain41z.dae on 24 April 2020: (very similar to 36z)
RESULT: WORKS!  In the sense that the Oculus animation matches that of the Mac Preview app
```    <channel source="#First_rotation_euler_Y-sampler" target="EntireEllipsoid/rotationZ.ANGLE"/>^M
```
```          <node id="EntireEllipsoid" name="OculusRift_EFE">
<translate>0.0 8.0 0.0</translate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  45.0</rotate>^M
<rotate sid="rotationX">1.0 0.0 0.0  0.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  0.0</rotate>^M
<scale sid="scale">4.0 4.0 4.0</scale>^M
...
```

NOTE: Earlier I tried to view a model — named "FullAgain35z.dae" and not discussed above — that I thought had exactly the same set of parameters as this model (i.e., the same as FullAgain41z.dae), but it failed to execute properly in the Oculus Rift S environment. I just performed a unix "diff" between these to model files and it identified two lines of code that were not the same, namely, the "rotationX" and the "rotationY" specifications for the "EntireEllipsoid" <node>. However, the only difference that I could see was that an extra blank space was in between two of the floating-point numbers in the pair of lines of code. I edited the "FullAgain35z.dae" file, deleting then retyping the two suspect lines, but the Oculus was unable to load the file. My conclusion is that the file is corrupted in some way and that it has been corrupted — and, as a result, very misleading! to my detective work — for the past couple of days.

• FullAgain42X.dae on 24 April 2020:
RESULT: WORKS!  In the sense that the Oculus animation matches that of the Mac Preview app
```      <float_array id="First_rotation_euler_Y-output-array" count="    2">^M
30.0^M
210.0^M
</float_array>^M
```
```    <channel source="#First_rotation_euler_Y-sampler" target="EntireEllipsoid/rotationX.ANGLE"/>^M
```
```          <node id="EntireEllipsoid" name="OculusRift_EFE">
<translate>0.0 8.0 0.0</translate>^M
<rotate sid="rotationX">1.0 0.0 0.0  30.0</rotate>^M
<rotate sid="rotationZ">0.0 0.0 1.0  45.0</rotate>^M
<rotate sid="rotationY">0.0 1.0 0.0  90.0</rotate>^M
<scale sid="scale">4.0 4.0 4.0</scale>^M
...
```

### Summary

When reading the following summary table — "What Works and What Does Not"— keep in mind that …

• the $~X_0$ axis aligns with the string of purple cubes, and the positive direction is defined by moving along this string of cubes toward the somewhat larger, purple rectangular box;
• the positive $~Z_0$ axis points up — the longest axis of the larger, purple rectangular box lies parallel to this axis;
• the $~Y_0$ axis is perpendicular to the $~X_0-Z_0$ plane and its positive direction is defined consistent with the right-hand rule — that is, it points from the line of purple cubes toward the center of the red ellipsoid; and
• initially, the three principal axes of the ellipsoid are aligned such that $~(a, b, c) \Leftrightarrow (X_0, Y_0, Z_0)$.

What Works and What Does Not
Model Desired Initial Orientation
of the Ellipsoid
Desired
Spin
WORKS?
FullAgain34y Turned +45° about the ellipsoid's intermediate (b) axis About the $~Y_0$ axis, from 45° to 180° Yes
FullAgain36z Turned +30° about the ellipsoid's intermediate (b) axis, followed by +45° about its shortest (c) axis About the $~Z_0$ axis, from 45° to 180° Yes

In order to get agreement between the two animation scenes — that is, agreement between what is seen using the Mac's Preview app and what is seen inside the Oculus Rift S home — it appears as though you must follow at least this list of rules:

1. The principal "rotation" axis that is highlighted by the <animation><channel><target> — for example, "EntireEllipsoid/rotationY.ANGLE" highlights the Y-axis — must be the first principal axis that is specified by the <rotate sid="…"> instruction inside the <node id="EntireEllipsoid">.
2. The value of the initial rotation ANGLE that is specified inside this first <rotate sid="…"> instruction — for example, 45° about the Y-axis — must match the starting value of this ANGLE that is specified in the <source id="…Y-output"> of the <animation> instructions.
3. The second and third instructions should be viewed as reorientations of the ellipsoid that must take place prior to the start of any animation. Given that this is only a pair of rotations (re-orientations), formally speaking they can be carried out in either order. But for clarity, let's always think in terms of carrying out the instructions from the bottom, up — i.e., the "third", followed by the "second", and finally the "first", which is also the animation specification.
4. CRITICAL INTERPRETATION: The "third" and "second" re-orientations involve rotations about the body axes (a, b, c) whereas the "first" rotation instruction (and subsequent animation) refers back to the frame axes (X0, Y0, Z0).

Let's use model "FullAgain42X.dae" as an example. Working from the bottom, up the three "rotation" instructions for the "EntireEllipsoid" should be carried out as follows:

1. rotationY = 90.0 means that the orientation of the ellipsoid is altered by turning it +90° about the ellipsoid's intermediate (b) axis.
2. rotationZ = 45.0 means that the orientation of the ellipsoid is altered a 2nd time by turning it +45° about the ellipsoid's shortest (c) axis.
3. rotationX = 30.0 along with the <animation><source> specification means that the (now, tipped) ellipsoid is spun about the frame's X0 axis from +30° to +210°.