Table of Contents

Introduction ............................................................................................................................... 3
The Problem ........................................................................................................................................ 3 The Project .......................................................................................................................................... 3 The Team ............................................................................................................................................ 3 A Note ................................................................................................................................................. 4

Original Requirements ............................................................................................................... 5
Introduction to the problem ............................................................................................................... 5 Project Description .............................................................................................................................. 5 Requirements:..................................................................................................................................... 5 Versions .............................................................................................................................................. 5 Design ................................................................................................................................................. 6 Specific tasks to be undertaken:.......................................................................................................... 6 Risk Assessment .................................................................................................................................. 7 Testing ................................................................................................................................................ 7 Preliminary Timetable ......................................................................................................................... 8 Roles of the different team members ................................................................................................. 9 Integration Plan .................................................................................................................................. 9 User interface requirements ............................................................................................................... 9 References .......................................................................................................................................... 9

Requirement Documents Revisited .......................................................................................... 10
The Perception .................................................................................................................................. 10

The True Gantt Chart ................................................................................................................ 11 The Engineering Expo ............................................................................................................... 12
Presenting our Project....................................................................................................................... 12 Final Poster ....................................................................................................................................... 12 The Aftermath................................................................................................................................... 12 Final Expo Poster ............................................................................................................................... 13

The Project ............................................................................................................................... 14
Setting up O3D .................................................................................................................................. 14 Acquiring COLLADA file ..................................................................................................................... 14 Parsing COLLADA............................................................................................................................... 15 Geometry .......................................................................................................................................... 15 Materials ........................................................................................................................................... 15 Final steps to render scene................................................................................................................ 16

How to install our project ........................................................................................................ 17 The Learning ............................................................................................................................. 18

1

Educating Ourselves .......................................................................................................................... 18 Our Site: www.ColladaWebViewer.com ........................................................................................... 18 W3C XML DOM: www.w3schools.com/dom/default.asp ................................................................ 18 O3D API: http://code.google.com/apis/o3d/ ................................................................................... 18 Our Mentor: Dr. Remi Arnaud .......................................................................................................... 18 Our Instructor: Dr. Mike Bailey ......................................................................................................... 18 Our Friend: Kyle Kendrick .................................................................................................................. 18

The Conclusion ......................................................................................................................... 19
Reminiscing ....................................................................................................................................... 19 What Now? ....................................................................................................................................... 19

Appendix .................................................................................................................................. 20
Appendix 1: Sample HTML Page ....................................................................................................... 20 Appendix 2: Parse Node ................................................................................................................... 20 Appendix 3: Create O3D shapes ........................................................................................................ 23 Appendix 4: Add shape to root.......................................................................................................... 25

2

Introduction
The Problem
In 2009 Google entered into the 3d web graphics world, with the release of an O3D API made available through JavaScript. The O3D API is an interface to a C plug-in that interacts directly with system hardware to render a 3d scene in any web browser. As a technology, 3d web graphics had a rocky start. In the early stages, the wrong attitudes towards 3d graphics were encouraged. Instead of framing 3d graphics through the internet, the 3d community began to take an application based perspective. This led to the creation of offline converters, the need to download and convert files, and overall encumbered the use of 3d graphics on the web. It was Dr. Remi Arnaud who requested this project. Dr. Arnaud recognized that an application based perspective on a web technology was the wrong step for 3d web graphics. He recognized that the most convenient way to view 3d content on the web would be to use standard internet URL mechanisms. This means being able to directly link and view the content, instead of packaging the content first. In order to further development of his view of 3d web graphics, Dr. Arnaud proposed a project to Oregon State University. The project was designed to create proof of this concept and provide an example for future 3d web graphics trends.

The Project
Dr. Arnaud envisioned a piece of software that would work based on the perspective of the internet. The software would link documents without the need of packaging and converting it offline first. He wanted to see if it was possible to directly visualize COLLADA (a standard 3d xml style representation of a scene) content in the browser. He chose to use Google s new 3d web graphics API, a new technology known as O3D, for the display of these web graphics. Using O3D, the software would parse a COLLADA file and render it as a 3d scene in the web browser. The software would be largely JavaScript dependent and would be easily embeddable into an HTML page. It would fetch a COLLADA file from any URL by using a PHP proxy. Once the software had access to the COLLADA file, it would use JavaScript to parse, translate, and draw the file using the O3D API. This would be done in such a way that the user would never have any indication that the file was a COLLADA file and not an O3D file. The possibilities for such software are nearly endless; users could potentially replace any web picture with an interactive 3d scene. COLLADA remains a very popular 3d graphics representation and is an exportable option in most 3d graphics programs. One potential example is that graphics students could export their work in a COLLADA file and display dynamic intractable 3d models instead of simple sprites as an example of their work.

The Team
The project came to Oregon State University as a Computer Science senior capstone project. In order to fulfill graduation requirements, students at OSU must complete a final project as proof of their mastery

3

of the curriculum. The senior capstone is a nine month project that is balanced on top of the general senior workload. The development team consisted of two seniors, Brandon Pearse and Ryan Lepinski. This project was a good fit for our team because we shared an interest in graphics, we wanted an exciting project, and we saw the potential for a project that would involve new technology. It was also helpful that we had worked well together in the past. The team spent a lot of time in meetings, instant messaging, and on the phone discussing the general layout and data structure of the project. Under the guidance of Dr. Arnaud our team began to take shape. As the weeks passed our team became more comfortable. We worked well together, being involved and interactive as the three of us strived to reach our goals. Under the supervision of Dr. Arnaud and with the help of a friend Kyle Kendrick, a 3d graphics graduate from the Art Institute of Portland, the project began grow into more than we expected.

A Note
The project really became something that we didn t expect. We have included the previous requirements document to show our original thoughts about the project. It is worth noting, however, that our perception on this project dramatically changed over the course of the project. We will discuss these changes in more detail in the Requirement Documents Revisited section below.

4

Original Requirements
Team Name
We make 3d look good.

Team Members
Brandon Pearse Pearseb@engr.orst.edu Ryan Lepinski Lepinskir@onid.orst.edu

Client/Sponsor/Mentor
Rémi Arnaud Remi@acm.org Screampoint

Introduction to the problem
Recently, Google released their competition to the webGL 3D browser plug-in. This relatively new technology known as O3D, may very well be the future in 3D web browsing. However, because the O3D is still new, the toolkit for using O3D is lacking.

Project Description
With their new technology, Google also released a toolkit that successfully provides an offline converter between COLLADA and O3D. However, this toolkit does not include any tools to directly load COLLADA content into a web browser. This particular tool could be built on the existing converter with a basic user interface that will lead to a more efficient process. Our team will build a user interface that will take in COLLADA data and directly display it into a web browser. When this functionality is achieved, we will have directly completed our goal.

Requirements:
Upon weighing the alternatives, our client has chosen to focus on O3D for this project. This will lead to a faster result, in addition to easier design. This in turn, will boost the success of our project and further the reusability of our tool. First and foremost, our tool should provide a simple and reusable interface that displays COLLADA data directly into a web browser. This tool will be built to allow for easy integration into an HTML page. It will have a simple interface that allows at the minimum; rotation of the object being presented and panning around the scene. The implementation of our user interface is yet to be determined.

Versions
Our team has decided in order to mitigate risk, we will release 3 versions. Our first version will be a simple prototype UI, this will have no functionality beyond providing valuable feedback from our client and allow us to reach middle ground before we implement functionality. Upon agreeing on the UI we shall move to implement functionality. This shall be our second version, at the end of this iteration we can present a fully functional product for inspection to the client. Based on the feedback we receive, the third and final version shall be a package of agreed upon and well tested functionality.

5

Design

Specific tasks to be undertaken:
Risk Management -- This will be an ongoing aspect of everything we do Weekly data backups -- To prevent loss of data O3D Research and discovery -- The more we know about the existing COLLADA to O3D the better COLLADA Data -- We have a good indication of where to find some of this for testing Version 1 Development -- This will implement the user interface for the tool Version 1 System and User Testing -- This will give us valuable feedback on the look of our interface Integration Testing -- We will need to make sure our interface integrates well in a web browser Version 2 Development -- This will implement functionality of the project Version 2 System and User Testing -- This will give us feedback on the performance of our software Integration Testing -- This needs to occur at the end of every version

6

Version 3 Development -- Final version for release, this will be a complete package for our software Version 3 System and User Testing -- This will be a final feedback opportunity before we finalize Integration Testing -- It will be nice to know it all works when we release it

Risk Assessment
There are aspects of O3D that have not been tested. Compatibility issues still exist, as well as the feasibility of a generic viewer. It is in the opinion of our team that these are not variables we can control therefore no risk management is needed on these aspects of the project. Because our project is graphically oriented, the design of the interface is very open to interpretation; to mitigate a potential disagreement we have determined to split our project into 3 versions to provide feedback on each piece individually. This slightly waterfall approach is very time intensive, however we are of the impression that it will lead to a satisfied client, in addition to a smooth interface. Another risk is always the possibility of data loss or corruption; we will do full project backups biweekly to prevent potential data loss.

Testing
We have built plenty of feedback sessions in with our client. We will provide layered testing for User, System, and Integration testing at the end of every version. This should provide us with more stable code and will in turn be a better solution than trying to test it all at once. In addition, if the opportunity presents itself for automated user tests we shall incorporate those into our project as well.

7

Preliminary Timetable
Task List

Figure 1.1: The list of our original tasks and time predictions.

Version 1

Figure 1.2: Gantt chart of the tasks and times described in Figure 1.1.

8

Version 2 and 3

Figure 1.3: Gantt chart of the tasks and times including version 2 and 3.

Roles of the different team members
Brandon Pearse -- Brandon will function as a loose project manager as well as being active in research, development and testing. Ryan Lepinski -- Ryan will be the key developer as well as also being active in research and testing.

Integration Plan
Both our coding styles and the nature of the project lend themselves to a paired programming method. However, if it becomes necessary to branch it into two projects we will agree upon a coding standard to increase readability as well as required commenting.

User interface requirements
Our user interface will be quite light. It is important our tool provides the ability for camera rotation around the drawn object, however the rest of the interface will be up to us.

References
Because O3D is a relatively new technology, we have direct access to the Google release notes. The wiki on this subject we found very resourceful and would recommend it to anyone coming up to speed.

http://en.wikipedia.org/wiki/O3D
In addition to O3D, a user hoping to learn more would also benefit from reading about COLLADA. http://en.wikipedia.org/wiki/COLLADA

9

Requirement Documents Revisited
The Perception
Though the requirements were never altered, the team faced dramatic perception changes throughout the life of the project. At the beginning of the project, we were of the impression that we were simply taking a closed source 3D converter program and making it work on the web. We knew coming into the project that there was already a COLLADA to O3D converter, and we thought we just needed to host it online. Dr. Arnaud truly understood what he wanted from the start. The development team, however, had little graphics experience and therefore didn t accurately estimate the depth of what needed to be done. Our view of the project changed every week for the rest of the year. The project has grown well; it started out as a proof of concept and ended up as a full open source project, complete with its own repository and bug tracker. Refer to Figure 2.1 and 2.2 to see our time allocations and the overall changes in our perception of this project.

10

The True Gantt Chart

Figure 2.1: Task list of what actually was worked on.

Figure 2.2: Gantt chart showing what we spent our time doing throughout the life of the project.

11

The Engineering Expo
Presenting our Project
The Engineering Expo was a great experience for us. It was a good opportunity to present the work we spent 9 months completing. There was a strong interest in our project and we received valuable feedback from the community. It was our first opportunity to explain the project to potential users and we are proud to report the positive response we received. The Expo went very well, and still remains our favorite part of the project. It was a great opportunity to see more potential uses of the project. After putting in so much time and effort it was rewarding to meet so many interested professionals who could find a use for the project. The Expo helped us realize that the potential success of this project easily surpassed that of our graduation requirements. We are now taking the opportunity to expand the project further.

Final Poster
The poster on the following page, along with a demo, was our display at the Expo. We collaborated with Kyle Kendrick in order to produce the poster.

The Aftermath
For lack of a better expression, we were inspired by the Engineering Expo. We saw how much interest there was in our project and we want to respond by expanding our involvement past the classroom. The most logical conclusion is to open the project up as an Open Source project, so that we can work with an open source community to get the best possible software on the market quickly. We created a website, hosted at ColladaWebViewer.com. By linking a git repository and Google Code bug tracker, we hope to watch the project grow significantly in the next few months.

12

Final Expo Poster

13

The Project
Setting up O3D
With any O3D application the first step is to create and initialize the O3D plug-in. The next step is to create the client area. When creating the client area, all of the divs within the HTML page with ids equal to o3d , will have an O3D client created inside them. This is the area where the scene will render. Once the client area is created, our program initializes our O3D global objects and libraries. This is where we create the namespaces for utilities libraries such as math and O3D, as well as pick to which client area we will draw. Next we create a render graph to draw the scene with. This render graph contains two different draw lists, one for opaque objects, and one for solid objects. A root object is also created to make it easy to transform the entire scene in the event of a rotate or zoom. The root object is an O3D object that will become a parent of any object in the scene. Our final step, before parsing the COLLADA file, is setting up our event callbacks. Event callbacks are listeners that call a method to deal with the event whenever a specified event occurs. In our program, we created 5 callbacks. To manage the user interface we created 4 callbacks that listen for the events mouse button up, mouse button down, mouse move, and mouse scroll. The other callback is used to ensure that the client area is at the correct size for each render.

Acquiring COLLADA file

Figure 3.1: Shows the process of using a PHP proxy to achieve cross domain loading.

14

Before parsing a COLLADA file, we must first have access to it. Since a COLLADA file uses xml, we chose to use an xmlHttpRequest object so we could access information using the XML DOM. This caused some issues with accessing COLLADA files. The first issue was xmlHttpRequest objects only allow parsing files with an XML mime type. This can be overridden but it would break compatibility with Internet Explorer 8, as Internet Explorer does not allow overriding the mime type. The second issue was doing cross domain loading. There are security issues with allowing loading xml from different domains, so xmlHttpRequest objects only allow same domain loading. This issue conflicted with our requirement to be able to load any COLLADA URL, even ones on different domains. Our solution to both of these problems was the creation of a PHP proxy. We had our xmlHttpRequest object make a request to our PHP proxy, passing along what URL it needed, and our PHP proxy would fetch the file and set the mime type to XML. This, however, requires some sort of proxy to be used on the server. We hope to find a client side workaround to this issue in the future.

Parsing COLLADA
Once we have access to the COLLADA file, we are able to parse out the required information by using xmlHttpRequest object. Using xmlHttpRequest objects made it very convenient to access any part of the COLLADA file. To do this, we make use of the XML DOM; specifically using getElementsByTagName, childNodes, and getAttributes. Using these 3 calls, we are able to access any needed parts of the COLLADA file.

Geometry
In our program, we first build an associative array of geometry objects. These objects contain all the needed information to render a mesh specified by COLLADA. Geometry objects hold the information about the geometry index array, normal array, texture coordinate array, tangent array, primitive type, as well as a unique material target. The material target is used later on to bind specific materials to the mesh. COLLADA geometries are located within the library_geometries tag. Each geometry tag contains a mesh, and within the mesh contains sources, vertices, and a primitive type. The sources for meshes are typically an array of float values that can be used such as tangents, indices, vertices, and so on. The vertices tag contains information for the meshes vertices, and the primitive elements contain the information of how to create the mesh. For each mesh, our program first creates an associative array of all of the meshes sources. Then it processes each primitive element type. Each primitive element, using the sources array and vertices node, creates an index in the geometry objects to be drawn later.

Materials
Materials are used to define the way a mesh appears in the scene. After creating an associative array of geometry objects, our program creates an associative array of materials for the scene. They are indexed by their material id. Each material object contains information about textures, colors, and what shader to use.

15

COLLADA materials are located in the library_material, and use information from library_images and library_effects. For each material tag, an index is created in the array. A material specifies an effect to be used within the library_effects. A COLLADA effect is created by first making a list of parameters to be used for a shader. The parameters can be a texture to be used as an image, or anything else that defines how a material looks. We chose to only support the effects found in the COLLADA common profile.

Final steps to render scene

Figure 3.2: Parse node flow chart to create the visual scene

Once our geometry and material object arrays are populated, we create the visual scene. This is done by parsing library_visualscene. The library_visualscene contains a tree like structure of nodes that tell how the geometry is placed in the scene. Transformations and material binding occur here. For objects added to the scene, the current transformation matrix and a material is passed to a helper function to add it to O3D. The first step is to create the actual O3D shape object. This is done using the geometry object. Next, a draw event is created for the object. Then a transform graph is created for the object and its transformation is set to the current matrix. Next the material is binding to the shape object. Finally, the transformation graph object is added to the O3D root object to be drawn. Appendixes 3 and 4 have sample code that shows creating and adding the shape, material, and matrix to O3D.

16

How to install our project
Installing our project is very easy. First you need to have moved our project on the server where the website will be hosted. On the included CD, the colladaWebViewer folder, you can also download the latest version from our git repository. More information can be found at colladaWebViewer.com. Once the project is uploaded to the server, in each web page that you want to use it you need to include two scripts before the body tag of the page. The first is the O3D base script located within the colladaWebViewer folder: colladaWebViewer/o3djs/base.js. The second is the colladaViewer script of our project: colladaWebViewer/colladaViewer.js. Next a div must be added to the page to create an O3D client area. This divs id must be set as o3d . The size of the created dive will be how large the viewer will become. Also, an input must be included for the URL. This can be anything from a form to a hidden tag as long as the id is set as colladaUrl . Our program will access the DOM searching for that id to find the COLLADA file to load. Two option inputs are id equal reset and id equal to load , if you want the users to be able to load different URLs or reset the current scene. An example web page can be found at Appendix 1.

17

The Learning
Educating Ourselves
The fact of the matter is that O3D was a very unrefined technology when we started our project. The available documentation was difficult to interpret and there were few relevant examples. We were using O3D API calls that were never used before in the examples that we could find. This was a process most users had no need to deal with, which led our team through a lot of trial and error discoveries. We did gather some insights from the following sites. Hopefully the future will bring better documentation, more examples, and further guidance to future users.

Our Site: www.ColladaWebViewer.com
Hopefully, our path to discovery will benefit those who follow. We created this website to allow others to learn more about our work. While the website is still in its infant stages, our goal is to provide a roadmap for anyone who chooses to follow in our footsteps.

W3C XML DOM: www.w3schools.com/dom/default.asp
This was a great site for helping us use JavaScript to transverse and parse the XML DOM in our ColladaViewer.js file.

O3D API: http://code.google.com/apis/o3d/
This is the link to the O3D API. It was without a doubt the single most important guide we had for our project. Much of our information was gathered from this website. It was a labor intensive process for us due to the new technology.

Our Mentor: Dr. Remi Arnaud
Dr. Arnaud was a huge help when faced with implementation issues. He did a great job of pointing us in the right direction from the start.

Our Instructor: Dr. Mike Bailey
A great help with all things graphics. We were truly lucky to have a graphics teacher in charge of our project. He helped us find equations, understand COLLADA, and answered our many questions.

Our Friend: Kyle Kendrick
A 3d graphics graduate from the Art Institute of Portland, he was an enormous help in putting the project together. His models and 3d graphic understanding were invaluable to this project. He helped design our website, our poster, and everything else that needed to look professional. His models, located on his portfolio website, were a major help to us and still remain our default presentation of what 3d excellence looks like. His portfolio website is www.kendrick3d.com, and is definitely worth checking out.

18

The Conclusion
Reminiscing
Looking back we have come a really long way. We found that leading a project to successful completion was rewarding and something to be truly proud of. Watching our project grow from nothing into something so unique was an awesome experience and the reason we became Software Engineer s to begin with. From a technical standpoint we gained valuable experience in using O3D, JavaScript, PHP, HTML, CSS, XHTML, XML, COLLADA, Agile Development Methodology, and project management. From a non technical standpoint we may have grown even more. We created something, virtually from scratch, that has the potential to become a major monument in the graphics world. Knowing the difference our project will make in the graphics world is probably the most valuable reward. We had an efficient team, good synergy, and a strong work ethic. We learned very little about conflict management as our team ran very smoothly. However, our experience with project management has just begun. We posted the project on Google Code and Gitorious so the project will live on past graduation. We now have the opportunity to expand our team size, go outside our comfort zone, and really learn what project management means. If we were to do it all over, we would have increased our mentor communication in the beginning. We believe it would have been valuable for all the parties involved to get to know each other earlier. If we would have had a better idea of the project from the start, we could have potentially made better use of the little time we had. With that being said, we are enormously proud of the work we did and believe we rose well above the call of duty.

What Now?
We want to take this opportunity to thank you for your interest in our project. As we mentioned before, we hope this project will grow significantly in the open source community. We believe this tool has a place in most websites and would be honored to watch over it while more talented developers join the team to help implement a great piece of software. So, if you know anyone who is looking to get involved, send them to our website to join our team. Always remember: We Make 3d Look Good.

19

Appendix
Appendix 1: Sample HTML Page
<html> <head> <title></title> </head> <body> <script type="text/javascript" src="o3djs/base.js"></script> <script type="text/javascript" src="./colladaViewer.js"> </script> <div id = "content"> <div style="border:2px black; border-style:solid; float:left; width:450px; height:450px"> <!--Client area --> <div id="o3d" style="width:450; height:425px"></div> <!--Inputs--> <div style="height: 25px; background-color:504b45";> <!²colladaUrl example --> <input type="text" size= "30" id="colladaUrl" value="http://kendrick3d.com/sampleCollada/tinyRocketeer.dae"/> <!²load example --> <input type="button" id="load" onclick="doload();" value="load"/> <!²reset example --> <input type="button" id="reset" onclick="reset();" value="reset"/> </div> </div> </body> </html>

Appendix 2: Parse Node
function parseNode(currentNode, libNodesNode, visualSceneNode, o3dOBjects, o3dMaterials, matrix) { //find the children of the current node var currentNodeChildren = currentNode.childNodes; var var var var currentMatrix = g_math.copyMatrix(matrix); geometryUrlList = []; nodeUrlList = []; innerNodeList = [];

for(var i = 0; i < currentNodeChildren.length; i++){ if(currentNodeChildren[i].nodeType == 3) continue; var nodeName = currentNodeChildren[i].nodeName; //parse the new matrix

20

if(nodeName == "matrix"){ var matrixString = getChildrensText(currentNodeChildren[i]); var newMatrix = g_math.identity(4); var l = 0; for(var j = 0; j < matrixString.length; j+=4){ newMatrix[0][l] = matrixString[j]*1; newMatrix[1][l] = matrixString[j+1]*1; newMatrix[2][l] = matrixString[j+2]*1; newMatrix[3][l] = matrixString[j+3]*1; l++; } //multiply the matrix of the old with the new currentMatrix = g_math.matrix4.mul(newMatrix, currentMatrix); } else if(nodeName == "translate"){ var translate = getChildrensText(currentNodeChildren[i]); for(var j = 0; j < translate.length; j++) translate[j]=translate[j]*1; currentMatrix = g_math.matrix4.translate(currentMatrix, translate); } else if(nodeName == "scale"){ var scale = getChildrensText(currentNodeChildren[i]); for(var j = 0; j < translate.length; j++) scale[j]=scale[j]*1; currentMatrix = g_math.matrix4.scale(currentMatrix, scale); } //a geometry to draw else if(nodeName == "instance_geometry"){ var geometryUrl = currentNodeChildren[i].attributes.getNamedItem("url").value.substring(1); //if(geometryUrl != "psycho_eye_headusOBJexport1Shape") // continue; var materialsList = currentNodeChildren[i].getElementsByTagName("instance_material"); var newMaterialList = new Object; for(var j = 0; j < materialsList.length; j++){ var targetUrl = materialsList[j].attributes.getNamedItem("target").value.substring(1); var symbolUrl = materialsList[j].attributes.getNamedItem("symbol").value; newMaterialList[symbolUrl] = targetUrl; }

21

geometryUrlList.push(new instanceGemoetryObject(geometryUrl, newMaterialList)); } //A url of a node Node to process else if(nodeName == "instance_node"){ var innerNodeURL = currentNodeChildren[i].attributes.getNamedItem("url").value; innerNodeURL = innerNodeURL.substring(1); nodeUrlList.push(innerNodeURL); } //just another node Node to process else if(nodeName == "node"){ innerNodeList.push(currentNodeChildren[i]); } else {// debugWriteLine(nodeName) }; } //process list of geometriesUrl to draw for(var i = 0; i < geometryUrlList.length; i++){ var url = geometryUrlList[i].geometryUrl; if(o3dOBjects[url]){ for(var j = 0; j < o3dOBjects[url].length; j++){ var symbol = o3dOBjects[url][j].material; var targetUrl = geometryUrlList[i].materialArray[symbol]; if(o3dMaterials[targetUrl]){ addShapeToRoot(o3dOBjects[url][j].geometryObject, matrix, o3dMaterials[targetUrl]); } else{ debugWriteLine("invalid o3dMaterial url: " + targetUrl); addShapeToRoot(o3dOBjects[url][j].geometryObject, matrix, o3dMaterials[-1]); } } } } //process the list of inner node nodes for(var i = 0; i < innerNodeList.length; i++){ parseNode(innerNodeList[i], libNodesNode, visualSceneNode, o3dOBjects, o3dMaterials, currentMatrix); } //process list of nodeurls. Throw error if cant find for(var i = 0; i < nodeUrlList.length; i++){ var libNodesList; var found = false; try{ libNodesList = libNodesNode.getElementsByTagName("node"); } catch (err){ }; if(libNodesList){ for(var k = 0; k < libNodesList.length; k++){ var id = libNodesList[k].attributes.getNamedItem("id").value;

22

if(id == nodeUrlList[i]){ parseNode(libNodesList[k], libNodesNode, visualSceneNode, o3dOBjects,o3dMaterials, currentMatrix); found = true; break; } else if( (k+1) == libNodesList.length){ debugWriteLine("could not find " + nodeUrlList[i] + " in library_nodes"); } } } if (found == false){ libNodesList = visualSceneNode.getElementsByTagName("node"); for(var k = 0; k < libNodesList.length; k++){ var id = libNodesList[k].attributes.getNamedItem("id").value; if(id == nodeUrlList[i]){ parseNode(libNodesList[k], libNodesNode, o3dOBjects,visualSceneNode, o3dMaterials, currentMatrix); found = true; break; } else if( (k+1) == libNodesList.length){ debugWriteLine("could not find " + nodeUrlList[i] + " in library_nodes"); } } }

} }

Appendix 3: Create O3D shapes
/*Creates an O3d primitve object based on a geometryObject input: GeometryObject output: O3d Primitive Object */ function createO3dPrimitive(geometryObject) { //create the o3d objects on the plugin var o3dPrimitive = g_pack.createObject('Primitive'); var streamBank = g_pack.createObject('StreamBank'); //associate the streamBank to the primitive streambank o3dPrimitive.streamBank = streamBank; //set the primitiveType to the passed in primitive type o3dPrimitive.primitiveType = geometryObject.type; //sets how many primitives there are in this object o3dPrimitive.numberPrimitives = geometryObject.count;

23

//set the number of vertices to the amount of positionArray/3, 3 entries per vertex o3dPrimitive.numberVertices = geometryObject.positionArray.length/3; //Create buffers containing the vertex position data. var positionsBuffer = g_pack.createObject('VertexBuffer'); var positionsField = positionsBuffer.createField('FloatField', geometryObject.fieldCount); positionsBuffer.set(geometryObject.positionArray); //Create buffers containing the vertex normal data. var normalBuffer = g_pack.createObject('VertexBuffer'); var normalField = normalBuffer.createField('FloatField', geometryObject.fieldCount); normalBuffer.set(geometryObject.normalArray); // Check to see if texCordArray has any values. if(geometryObject.texCoordArray.length !=0){ //Create buffers containing the vertex texcoord data. var texBuffer = g_pack.createObject('VertexBuffer'); var texField = texBuffer.createField('FloatField', 2); texBuffer.set(geometryObject.texCoordArray); // Associate the texture Buffer with the StreamBank. streamBank.setVertexStream( g_o3d.Stream.TEXCOORD, // semantic: This stream texture coordinates 0, // semantic index: First texture coordinates stream texField, // field: the field this 0); // start_index: How many skip in the field. } // Check to see if tangentArray has any values. if(geometryObject.tangentArray.length !=0){ var tanBuffer = g_pack.createObject('VertexBuffer'); var tanField = tanBuffer.createField('FloatField', 3); tanBuffer.set(geometryObject.tangentArray); streamBank.setVertexStream( g_o3d.Stream.TANGENT, 0, tanField, 0); } // Check to see if binormalArray has any values. if(geometryObject.binormalArray.length !=0){ var binormalBuffer = g_pack.createObject('VertexBuffer'); var binormalField = binormalBuffer.createField('FloatField', 3); binormalBuffer.set(geometryObject.binormalArray); streamBank.setVertexStream( g_o3d.Stream.BINORMAL, 0, binormalField, 0);

stores vertex (and only) stream uses. elements to

24

} // Associate the positions Buffer streamBank.setVertexStream( g_o3d.Stream.POSITION, // positions 0, // position stream positionsField, // 0); // in the field. with the StreamBank. semantic: This stream stores vertex semantic index: First (and only) field: the field this stream uses. start_index: How many elements to skip

// Associate the normal Buffer streamBank.setVertexStream( g_o3d.Stream.NORMAL, normals 0, normal stream normalField, 0); skip in the field.

with the StreamBank. // semantic: This stream stores vertex // semantic index: First (and only) // field: the field this stream uses. // start_index: How many elements to

//Set the IndexBuffer to an indicesArray var indexBuffer = g_pack.createObject('IndexBuffer'); indexBuffer.set(geometryObject.indicesArray); //Associate the triangle indices Buffer with the primitive. o3dPrimitive.indexBuffer = indexBuffer; //Return the shape return o3dPrimitive; }

Appendix 4: Add shape to root
/* addShapeToRoot adds a new shape to the o3d draw event input: geometryObject - geometryObject to create a primitive from matrix - transformation matrix material - what material to appply */ function addShapeToRoot(geometryObject, matrix, material) { var primitive = createO3dPrimitive(geometryObject); var o3dShape = g_pack.createObject('Shape'); //set the owner of the Primiitve to the o3dshape primitive.owner = o3dShape; //create a new transform Object var transformObject = g_pack.createObject('Transform'); //Add every shape in shapes to the new transform object transformObject.addShape(o3dShape);

25

//transform the object transformObject.localMatrix = matrix; o3dShape.createDrawElements(g_pack, material); //add it to root to be drawn transformObject.parent = g_root; }

26

Sign up to vote on this title
UsefulNot useful