Updated: 3/1/2004; 8:01:43 AM.
a hungry brain
Bill Maya's Radio Weblog
        

Friday, February 06, 2004

Dream Jobs of 2004 [Slashdot]    

A Deep Space Primer [Slashdot]    

Juvenon. Youth pills [Cool Tools]    

The Future of Ideas. Exploring the weirdness of shared ideas [Cool Tools]    

A Garden from a Hundred Packets of Seed. Cheapest way to grow [Cool Tools]    

Device independence.
For a team of collaborators, Groove synchronizes both the sets of applications available in a given context (or "shared space") and the data written by those applications. If you drop your laptop on the floor you can effortlessly recover everything into a fresh instance of Groove on a new machine.

Of course this works only for native Groove apps. Browser history and bookmarks, Outlook settings, and a million other things are handled in a million other ways -- or not handled at all -- because desktop operating systems aren't Groove. A general solution would require OSs that work like Groove, and applications that send messages rather than write files. Well, come to think of it, why not? [Full story at InfoWorld.com]
... [Jon's Radio]    

The World of Virus Writers [Slashdot]    

Amazing Iraq photo website from Stephanie Sinclair.



A weblog and an incredible collection of images from Iraq (also Cuba), shot and written by photographer Stephanie Sinclair. Click thumbnail for full-size image. No "wardrobe malfunction" jokes, okay?

link

(note: Her blog and photo gallery launch by way of a nasty javascript pop-up window, but the UI is well worth enduring for the truly stunning images inside)

(Thanks, Sean)
[Boing Boing Blog]

    

Age-maps: cool photoshoppery to span the years.

Less sez, "Two photographs of the same person, from different periods of time (child and adult) are spliced together. In this fusion a jump-of-time is established at the tear."

Link

(Thanks, Lee!)


[Boing Boing Blog]    

Here are some proposals and documents I've written, describing the work I've done and projects I've proposed with The Sims character animation system, plug-in objects and tools. After four years, a great deal of useful information has been reverse-engineered by independent third-party developers and open source projects like The Sims Technical Library. I hope these ideas will inspire more tool developers to contribute their programming skills to the Sims community.

    

Wolfram's giant book free online. Stephen Wolfram has made the complete text of his New Kind of Science (a 1000+-page treatise on the way that virtually everything in the universe can be explained with cellular automata), which he self-published a couple years back with some of the squillions of dollars he's earned on his seminal Mathematica software program, available for free on the Internet.

Link

(via /.) [Boing Boing Blog]    

How to Grill. From BBQ to chef [Cool Tools]    

HourWorld. Handy global time zone clock [Cool Tools]    

Vet-Wrap Conforming Bandage. Inexpensive secure bandages [Cool Tools]    

PalmSource reveals new OS plans for cell phones. PalmSource has revealed that it has new plans for its OS line-up. The company appears to be making aggressive moves to get their Operating Systems into a wide variety of cell phones [Ars Technica]    

Embedded Ethernet and Internet Complete [Slashdot]    

The Swarmbots Are Coming [Slashdot]    

Test Prep on Your PDA.

Handmark® and Kaplan Test Prep and Admissions Sign Long Term Publishing Agreement

"Handmark®, the # 1 publisher of software for both Palm OS® and Windows Mobile™ platforms for handheld devices, has signed a long term publishing agreement with Kaplan Test Prep and Admissions, the world leader in test prep and a division of global educational services provider Kaplan, Inc. Handmark will publish a variety of test preparation and admissions testing titles sold through online distribution and in retail packages. The comprehensive agreement covers test prep titles such at ACT, SAT/PSAT, GRE, and others for Palm OS based devices as well as for Windows Mobile for Pocket PC and Smartphone platforms.

The first titles, based on Kaplan ACT and SAT test preparation materials, will be available for back-to-school shopping in the summer of 2004...." [Handmark, via Daily Palm]

I wonder if libraries will be able to circulate these titles.

[The Shifted Librarian]    

  RSS Winterfest SocialText Wiki - Authenticated, Encrypted RSS page:



    

Innovative Blog.

Very cool - the Addison Public Library is using a blog to detail its Journey to Innovative, a new computer system for their catalog!

[The Shifted Librarian]    

basecampHQ.com.

BasecampHQ launches. definitely worth taking a look at this project management app [anil dash's daily links]

Jason Fried (Mr. 37Signals - the creators of basecamp.com) sent me a link to it today. It looks coolio.

[Marc's Voice]    

Snippets from Al-Qaeda's bi-weekly e-zine (quotes from bin Laden):

"We continue on our path and in our Jihad against America. We continue to strike at America and we expect that our next blow will cause the collapse of the situation [in Saudi Arabia] due to the vengeful response, the first result of which will be the direct occupation of the oil sources and America's entrance [into Saudi Arabia] with the aim of changing the situation from its foundations."

"It will be a surprising blow, that is, one that is completely unexpected. They cannot conceive or imagine the way in which it will be carried out… It is a great blow. That is, the losses that will be caused to America and the Western world in its wake will be very great. Due to its magnitude, the blow will change the international balances of powers…"

It looks like bin Laden is starting to move towards a failed state strategy (which is very smart and very bad for us). The lesson of 9/11 - Iraq was not lost on bin Laden. If they can sucker the US into Saudi Arabia (there are a couple ways to do this that are very counter-intuitive), we will have truly lost. [John Robb's Weblog]

    

This is a great report (pdf) on the psychology of terrorism put together by the Federal Research Division of the Library of Congress (dated: September, 1999). The upshot is that the report sagely concluded that Al Qaeda represented the only viable threat against the US. Whatever form an attack may take, bin Laden will most likely retaliate in a spectacular way for the cruise missile attack against his Afghan camp in August 1998. [John Robb's Weblog]    

How to Stop Worrying and Learn to Love the Internet. (via Kevin Marks) - A classic that should be read over and over again by us Over-30 old farts!

[Roland Tanglao's Weblog]    

Built By Hand. Best of vernacular buildings around the world [Cool Tools]    

Architecture Without Architects. Highly-evolved home design [Cool Tools]    

MySQL: Building User Interfaces [Slashdot]    

Learning Computer Science via Assembly Language [Slashdot]    

Running a Business on Open Source Software? [Slashdot]    

Confession time. It's time for a confession. I've been acting as though all this cool XPath search stuff I've been demonstrating for the past few weeks were based on plain vanilla XHTML. Well, it's not (quite) true. In general my point has been to illustrate two things:
  1. That the XHTML equivalent of ordinary HTML content includes metadata (links, tables, images) that can be usefully exposed as XML. ... [Jon's Radio]

    

For RealNetworks, when it rains, it pours. RealNetworks struggles with security flaws, profitability, and lack of respect. [Ars Technica]    

Game.Ars and the rise of the console. Game.Ars returns with a look at a somewhat surprising story of 2003 — the ascendancy of console gaming [Ars Technica]    

New IBM laptop saves both weight and files. IBM's X40 lets users recover data from their computer, even if the system is damaged. [Ars Technica]    

XML Pie Menus.

Chris, a computer science student from digipen.edu who's interested in user interface design, asked me some interesting questions about pie menus:

First, were you happy with The Sims' implementation of pie menus? It seems as though it doesn't necessarily provide all of the great features of an ideal pie. The targets aren't infinitely 'deep' -- the user needs to click directly on the button. Perhaps more importantly, the targets aren't in predictable locations (they items are dynamic based on a very complex set of inputs.) Don't misunderstand; I loved the game and felt the the interface worked well. I am interested in the design decisions that were made.

The other thing I wanted ato ask was, have you any opinions on the game Sacrifice? I was very drawn to its pie system, and am always surprised that there has really never been much mention of it when it comes to discussion of pies, and pies in games. Thank you for your time,

Chris

Thanks for your thoughtful questions!

I'm glad to hear fasteroids still works after all those internet explorer patches that have come out since I wrote it. I hope the Eloas patent doesn't force Microsoft to break browser plug-ins like fasteroids and pie menus on purpose.

I'm pretty happy with the way The Sims pie menus turned out, considering the time and design constraints. But of course there are several things about them I would change and extend if I had the time.

Each time I've implement pie menus for different systems, I've taken different approaches, depending on the needs of the application and the capabilities of the platform.

For a game like The Sims, the game design was primary and everything flows from that. So the items on the menus had to change, because that's what the design called for. It might have been possible to make them stick to preferred directions, but I couldn't think of any obvious design that would work for the wide, open-ended range of objects and actions they'd have to display, which wouldn't make it more difficult to create objects, and wouldn't require revisiting and fixing all the objects that were already produced.

The Sims pie menus were something I whipped up one night and just checked into the code base, and then gradually evolved over time. But since they weren't part of the primary game design, I couldn't make them do anything that would throw a monkey wrench into the object creation or programming process. They're implemented as a custom subclass of the Sims user interface framework widget, but the code reaches out and touches many different layers of the game (the simulator, the 3D character animation layer, the 2D user interface layer, the pixel based image processing layer). They're designed to automatically present dynamically generated pie menus, and they always have the same graphical appearance. So they don't support any editor control panels or customizability features. The way they handle overflow items is far from ideal.

I implemented the ActiveX pie menus in C++ prior to working on The Sims, and my approach to designing a reusable pie menu component was much different the approach I took to The Sims pie menus.

http://www.piemenu.com/ActiveXPieMenus.html

http://www.piemenu.com/PieMenuDescription.html

The ActiveX pie menus had many convenient and experimental features, and featured configuration control panels so user interface designers can easily customize them with tools like Visual Basic. They tried to be everything for all people, so the design was stretched in many different directions at once, instead of being focused on a single application. They're easy for designers to configure, but they don't give you much control over how they appear. The C++ code was getting complex and hard to maintain, because it had to do all the dynamic layout and rendering itself, without the help of a web browser. They suffered from html-envy, and I didn't feel like re-implementing Internet Explorer just so you could put animated gifs and blinking green text in your pie menus. So if you can't beat them, join them.

Much later, I implemented the JavaScript pie menus after working on The Sims, and my approach was focused on making an open xml-based interface that would be useful for web designers and online services, and leverage existing technology instead of trying to re-implement it. The xml menu specification is primary; the implementation that turns the xml into pie menus is secondary, and replaceable. The JavaScript pie menus are much simpler than the ActiveX pie menus, they let you totally control their appearance with dynamic html, and they leverage the web browser, JavaScript and XML, instead of trying to do everything themselves. They're lacking in the keyboard navigation department, and it would be nice to be able to pop them up in their own independent window, that could overlap frames and extend outside the browser window.

Even though they lack many of the features of the C++ ActiveX pie menus, I like the JavaScript pie menus best, because they're so simple and flexible. You can drop down to JavaScript and DHTML to make them do anything they don't already do. They're more like an extensible framework that you can populate with XML, JavaScript, HTML and other browser-based technologies (like VML, used to implement the graphics in Fasteroids), instead of being a monolithic component like the ActiveX control.

I've used the JavaScript pie menus in several different projects since I wrote them a few years ago. I've learned a lot more about JavaScript object oriented programmer since then, and they're long due for a rewrite. They need to be extended with some of the useful features of the ActiveX pie menus like paging, keyboard navigation, browsing, editor control panels, etc.

The code needs to be cleaned up so it works in any browser, and also other JavaScriptable graphical systems like SVG and Flash. I like IE's Dynamic HTML Behavior controls, but I think it would be best to write some clean JavaScript classes that worked in any browser, and then simply package them as a HTML Behavior Control for Internet Explorer, so you'd have one set of code that worked well in all browsers. I've ported the pie menu and fasteroids code to SVG (Scalable Vector Graphics, like PostScript for XML that you can animate like dynamic HTML with JavaScript, DOM and CSS).

Adobe's SVG viewer can do some beautiful amazing stuff, in real time! Now that JavaScript is the lingua franca of the web, it would be great to factor out all the graphics and input from the core pie menu class, so you could subclass the generic pie menus for Flash, SVG, Dynamic HTML, etc. They should be all based on the same core xml pie menu format, that enables you to include embedded visual representations like html, svg and flash.

Presently, the HTML-based JavaScript pie menus let you include an tag in any or , containing arbitrary xhtml that defines its appearance in the web browser, overriding the automatically generated label.

I propose to generalize that so you can also have other types of tags like and (given some way to represent flash in XML, or point to named objects in a separate flash file). It should also support a standard set of high level generic tags like and , that the implementations would translate into the native representation like tags or Flash objects.

One of the great ideas behind xml is abstraction and reusability: to enable you the author to write what you MEAN at a high level, instead of the low level details about how to do it, so many different implementations can translate your high level intentions into their own internal low level implementation details. That's why it's so great for describing user interfaces like pie menus.

I've also developed a Palm application with pie menus for the touch screen: ConnectedTV turns your Palm into a universal IR remote control integrated with a personalized TV guide. It's designed so you can use it with one hand, without a stylus. You can stroke the buttons with your finger, to invoke different commands in different directions. For example: stroke left and right to page to the previous and next program; stroke up to change the channel to the current program; stroke down to read more about the current program; stroke the ratings button up to add a program to your favorites list; stroke it down to add it to your bad programs filter.

http://www.Connected.TV

I haven't seen Sacrifice, but thanks for pointing it out to me -- I'll look it up and check it out.

[Don Hopkins' RadiOMatic BlogUTron]    

A Proposal to Develop Third Party Content Authoring Tools for The Sims.

This is a propsal I wrote to Maxis after The Sims was released in March 2000, outlining some of my ideas for third party content authoring tools that I could develop. This led to The Sims Transmogrifier, but it touches on several other interesting tools and projects that Maxis never got around to.

A Proposal to Develop Third Party Content Authoring Tools for The Sims
by Don Hopkins, March 2000

Problem Definition:

  • There is a strong demand many from third parties who want to develop their own custom content for The Sims, including characters and objects.

Proposed Solution:

  • Update, clean up and document the content creation tools, so third parties can make their own characters and objects for The Sims.
    • Port the tools to the latest version of 3D Studio Max.
    • Make the tools self contained so they can be run stand-alone, by removing all dependencies on the Maxis environment and expensive software packages: Character Studio (Biped, Physique), Access, SourceSafe, MKS Toolkit (Korn Shell).
    • Document the content creation tools with an overview, examples, tutorials, and a reference manual. Write down the folklore that has been passed by word of mouth. Read over the code and document how it actually behaves.
    • Provide consulting, training and content creation services to third parties who want custom content authored for The Sims, but don't want or know how to do it themselves.
  • Develop a Sims Content Authoring SDK, so it's possible for third parties to create specialized content creation tools, like FaceLift.

Goals:

  1. Third Party Character Creation and Customization:
    • Characters include virtual people who the user can play with, as well as autonomous non-player characters with programmed behaviors. Characters consist of bodies, heads and hands of 3D polygonal meshes with texture mapped bitmap skins.
    • Characters are created at Maxis by highly skilled artists using expensive tools like 3D Studio Max, Character Studio, the CMX exporter, and Photoshop.
      • Simplify the content creation tools and make them run stand-alone, so third party artists and designers can create their own characters and objects.
    • Maxis' expert 2D character artists currently use Photoshop to paint body textures in layers, then flatten and dither them into 256 color bitmap files.
      • "Flesh out" the process of applying layered clothing to naked bodies and dithering to 8 bits, so anyone can dress up their characters in all kinds of clothes.
    • Maxis' expert 3D modeling artists create textured low-poly rigid meshes (like heads, hands and accessories) attached to individual bones, and the CMX exporter creates rigid suits.
      • Make the CMX exporter easy for third parties to use, so many proficient 3D artists will be able to make their own textured heads, accessories, selected character pointers, and carried objects.
    • Maxis' expert 3D character modeling artists attach textured low-poly deformable meshes (like bodies) to skeletons using Character Studio Physique and Biped, and the CMX exporter reads out the weighted vertex/bone bindings and creates deformable suits for the game.
      • Character Studio is an expensive plug-in that enables a skilled artist to bind deformable meshes to skeletons, but there are other ways to do that with 3D Studio Max and other 3D tools.
      • Enhance the CMX exporter to support Max's new way of attaching deformable meshes to skeletons, so third party 3D artists can create bodies.
    • Maxis designers and programmers use the Edith tool to configure the behavior of characters and objects.
      • Clean up and document Edith, so third party designers and programmers can program and modify their own characters and objects.
  2. Third Party Object Creation and Customization:
    • Objects consist of pre-rendered z-buffered sprites, packaged together with character animations, sound effects and programmed behavior.
    • Objects are created in-house at Maxis, by highly skilled 3D modeling artists, using lots of polygons and detailed texture maps in 3D Studio Max. The sprite exporter breaks the objects up into tiles and renders them in different scales and rotations, then writes out z-buffered sprites.
      • Clean up and document the sprite exporter, so third party artists can use it with 3D Studio Max to make their own objects.
      • The sprite exporter is very specific to 3D Studio Max, especially when breaking apart multi-tile objects.
    • Maxis' expert 3D character animation artists create skeletons and animations of characters interacting with objects. They use Character Studio Biped, although the exporter supports other types of skeletons, like the bones built into Max or even hierarchies of normal objects.
    • Clean up and document the CMX exporter, so third party character animators can use it with 3D Studio Max with or without Character Studio to make their own character animations.
  3. Enable Third Party Content Creation Tool Development:
    • Develop and document an SDK (Software Development Kit) that gives third parties the information they need to make their own content creation tools for The Sims.
    • Enable and encourage the development of tools like FaceLift and Blueprint by third parties.
      • A "BodyLift" tool that enables anyone to mutate, breed and tweak deformable body meshes, like FaceLift lets anyone do with rigid head meshes.
      • A skin tool that enables anyone to layer clothes and accessories on different bodies, skin colors, sexes, ages, etc. Allow artists to create 32 bit alpha masked layers of clothing that can be applied to any body.
      • An animation tool that enables anyone to create their own dance sequences, walk loops and idle animations, by mixing, cross fading and mutating between many pre-existing dramatic poses, dance moves, walks and idle loops.
      • Specialized object creation tools that enable anyone create their own customized objects from templates, like a PictureFramer that would create a framed picture from any bitmap, or a JukeboxFactory that would create a jukebox full of your favorite mp3 files.

[Don Hopkins' RadiOMatic BlogUTron]    

VitaBoy Documentation.

VitaBoy Documentation

By Don Hopkins, Maxis.

This document describes VitaBoy, the skeletal character animation system in The Sims, written by Don Hopkins at Maxis.

VitaBoy combines several different types of data together to render the animated characters in the game, including skeletons, skills, suits and texture maps.

Artists create the skeletons, skills and suits in 3D Studio Max, and the texture maps in Photoshop.

The CMX Exporter is a 3D Studio Max plug-in and MaxScript user interface, which allows artists to export skeletons, skills and suits from Max files into CMX files that the game can read.

Character Studio is another 3D Studio Max plug-in, that allows artists to animated a Biped skeleton, and to attach deformable mesh suits to it with Physique. The CMX Exporter knows how to support Character Studio Biped and Physique, but it can be used with other kinds of skeletons and suits as well.

The way the CMX Exporter knows what to export from a Max file, is by looking for note tracks on the bones, for keys containing tags that control the exporter. The artist inserts note track keys into the Max file, to mark up the skeletons, suits, skills and events. The tags in the note track keys tell the exporter what to export from the Max file.

The Access database tells the exporter which skeletons, skills and suits are defined, which Max files contain them, and where to export them. The artist can select the name of a skeleton, skill or suit from a scrolling list, and automatically load, validate and export the correct Max file to the correct destination. The exporter can also check the exported files out from and into SourceSafe. The artist can use the exporter manually without the database, but the database is extremely useful for avoiding accidents when there is a lot of content to manage.


· Installing the CMX Exporter.

o The "official" distribution site of the CMX exporter is ElmoctgrpubDISTMaxScript CMX Exporter.

o The CMX Exporter is implemented as a MaxScript plug-in (maxiscrp.dlx) and a MaxScript startup script (maxis-maxscript.ms). It’s not a normal 3D Studio Max “exporter” plug-in, so you will not find it on the File/Export menu, instead it has its own user interface utility panel.

o To install the CMX exporter, first quit Max, then copy the plug-in maxiscrp.dlx to your 3dsmaxPlugins directory, and copy the script maxis-maxscript.ms to your 3dsmaxScriptsStartup directory.

o Finally, restart Max.

· Updating the Database Cache.

o The old CMX Exporter used to dynamically download the database from Access via OLE Automation, but that had problems and was slow, so we switched to a simpler more reliable approach of generating a text file from Access that MaxScript can read quickly, instead using OLE.

o In order to use the CMX Exporter with the Access objects database, you must open up the objects database in Access, which lives at [??? TODO…], and run a macro called [??? TODO…].

o This macro that exports a cache of the interesting parts of the database as MaxScript code that reads in very quickly.

o You must run it every time part of the database that matters to you changes, and then you must quit and re-start Max in order to read the updated database cache. (Dynamically reloading the cache would be an easy feature to add, though.)

o After running the macro, you can quit Access if you want to be polite.

· Running the CMX Exporter.

o To use the CMX exporter, first you open up Max's "Utilities" panel, then select the "MaxScript" utility.

o MaxScript will initialize and automatically load in the scripts in the Startup directory.

o Next, select the "CMX Exporter" item from the Utilities menu in the MaxScript panel.

o Then, the “Load CMX Exporter” panel will open up below.

o The “Load CMX Exporter” panel has a button called “Load CMX Exporter Cache”, that loads the animation database from cache files, which an Access database macro wrote out into the local temporary file directory.

§ In order to use animation database, you must first open up the Objects database in Access, and execute the macro called [TODO: ???], which updates the cache from the database.

§ After it loads the database cache, the “CMX Exporter Turbo-Deluxe” utility window will open up, with a scrolling list that lets you select any animation or suit in the database.

o If you don’t need to use the database, and want to run the exporter manually, press the button called “Open CMX Exporter”.

§ The “CMX Exporter Turbo-Deluxe” utility window will open up, but the scrolling list will not have any items in it. You can still operate the exporter manually, with the other buttons in the window.

o Now you can close the Utilities, MaxScript and “Load CMX Exporter” panels to leave more room for the CMX exporter.

· Using the CMX Exporter.

o The scrolling list in the CMX exporter contains the names of all skeletons, suits, and skills in the database that are checked for export.

o Select the name of a skill or suit or skeleton from the list.

o The Max file name and the status are shown in text fields below the list.

o Press "Load This Max File" to load the max file containing the currently selected database entry.

o Press "Load And Export This Max File" to both load and export the selected database entry.

o The CMX directory and file name are shown below the buttons.

o There is a "Write Enable" check box that you can uncheck to prevent the exporter from writing any files.

o Good for a dry-run before the output files are checked out, to see which files will be exported.

o The Check In and Check Out buttons attempt the check the output files in and out of SourceSafe.

o They don't check in or out the Max source file, however -- you have to do that yourself.

o The "Export Current Max File Here" button exports the currently loaded max file to the location as specified by the selected database entry.

o Make sure the right database entry is selected.

o If the max file name and the cmx file name are different, you are warned and given a chance to abort.

o The max file name and the cmx file name should always be the same (except for their extensions),

o and there is no reason to make them different, so usually something's wrong if you get that warning

o (like a different entry selected than max file loaded).

o The "Export Current Max File To..." will prompt you for the cmx file and directory to export the currently loaded max file, ignoring the selected database entry. This button will work even if the database is not loaded.

o The "Export Max Files in List" button lets you list the names of a bunch of max files to export in a text file.

o It will load and export each of those files (the names can be absolute or relative to the directory containing the text file of names).

o The "Filter" field allows you to specify a database "Keywords" filter.

o The 3DRT and Animation databases have a "Keywords" field that is for exporter filtering keywords.

o If you type a string into "Filter", the exporter will only export database entries that have that string in their Keywords field.

o Look at the databases to see the keywords that have been defined.

o If you need to repeatedly export a group of animations or suits, you can make keywords to describe them, and enter them into the database,

o so it's easy to use the exporter to batch export just the subset you're interested in (like all suits and animations associated with a named character, would use the name as a keyword).

o The "Export Files In Database" button loads and exports all max files in the database (subject to the filter), including skeletons, suits, and skills.

o It prints out a summary report of the successful exports and failed exports with error messages.

o The "Load Files In Database" button just loads all max files in the database, to make sure they're there and valid.

o It prints out a summary report of the successfully and unsucessfully loaded file names.

o TODO: Describe how to batch export all the Max files in the database in chunks, to work around 3D Studio Max corruption.

· Marking Up Note Tracks and Tags

o Max allows you to attach a note track to any object in the scene, and place keys on the note track in time, whose string value you can edit in a little text editor window.

o Note track keys attached to bones at certain times allow you to control the exporter, and insert user definable events into animations.

o The CMX exporter parses the note tracks as a TimeProps. Each note track key exists at a particular time, and contains a multi-line text field.

o The text field is parsed as a Props, each line in the format “tag=value”.

o The format “tag” (without an = sign) is a shorthand for “tag=”, which defines the tag to be a zero length string. You can use certain shorthand tags like “moving”, “absolute” and “relative”.

o Be careful not to include any blank lines in the multi text editor, or the CMX text file reader might get confused (this is a bug that should be fixed).

o Skeletons

§ The “skeleton=name” tag marks the root of a skeleton, used for exporting suits or skills. A normal skeleton is not exported like a masterskeleton. You have to tag the skeleton, so the exporter knows where to look for Skills and Suits.

§ The “masterskeleton=name” tag marks the root of the master skeleton, which is actually exported. There should only be one master skeleton of each name (currently “adult” and “child” in The Sims).

§ The “cantranslate=value” tag marks a bone as having its translation animated, which is false for all bones by default. For Biped, this includes the root and the pelvis. The value should be 1 or 0. The CMX exporter sets this automatically for Biped skeletons, but if you make your own skeleton you might need to use it.

§ The “canrotate=value” tag marks a bone as having its rotation animated, which is true for all bones by default. The value should be 1 or 0.

§ The “canblend=value” tag marks a bone as being blended, which is true for all bones by default. The value should be 1 or 0.

§ The “wiggle=canWiggle wigglePower” tag sets the canWiggle flag (1 or 0) and wigglePower value (a floating point number) of the bone. The format is “int float”. This adds Quaternion Perlin noise to the bone rotation. This is not currently used.

§ The CMX exporter has special support for Biped skeletons. Put the “skeleton=name” tag on the biped root (usually called “Bip01”). The “Bip01” root is renamed “ROOT” in the export process, and all the bones are stripped of their “Bip01 ” prefix and canonicalized. Dummy and Footstep nodes are ignored.

§ The CMX exporter also supports Bones or other 3D Objects as skeletons. The trick is to name the bones using the same conventions as the Biped bones: the root should be tagged with “skeleton” or “masterskeleton”, and be named “Bip01” (or anything else, as long as you’re consistent), and all the bones under that are named “Bip01 BoneName” (don’t forget the space). The exporter recognizes the bones under the root by their prefix (the name of the root followed by space), and assumes anything that doesn’t have that prefix is a skin (a mesh to be rendered, instead of a bone of the skeleton). So every bone of the skeleton should have the prefix of the root (plus a space), so the prefixes are stripped off, and the root is renamed “ROOT”. Kind of weird, but that’s how Biped does it.

o Suits

§ To export a suit, attach a “suit=name” tag to the root of the skeleton, at the time you want it to export.

§ You can animate objects over time and export several suits on the same skeleton at different times, which snapshot its different states at the times of the suit tags.

§ Rigid Meshes

· Rigid 3D meshes can be attached to parent bones, or other rigid meshes descendent from a bone. All rigid meshes descendent from a bone are exported in the bone’s coordinate system, and move with the bone.

§ Deformable Meshes

· Deformable meshes can straddle more than one bone of the skeleton, so they bend smoothly with the skeletal animation.

· Different vertices of the same mesh are attached to different bones, so the mesh moves with the skeleton.

· Some vertices may be attached to two bones at once, with a different weight for each bone, so that the seam between bones deforms smoothly.

· The CMX exporter supports using Physique to bind deformable meshes to Biped skeletons, and knows how to read out the vertex to bone bindings and their weights. It does not support the fancy vertex binding types (bulges and tendons, etc), just the rigid weighted style, attached to no more than two bones.

§ The “type=value” tag controls the suit type, defaulting to 0. The normal type 0 Suit has faces, and the type 1 Suit just transforms vertices, and is used by censorship for bounding box calculation.

§ The “flags=value” tag on a skin sets the skin flags, which make it possible to filter out a set of skins when dressing a suit, and is used by censorship to select which bounding boxes of a type 1 suit to censor.

§ The CMX Exporter writes out the texture map coordinates of the vertices, and the name of the texture map, which should be installed separately or bundled with an the object.

§ Put the texture map into a bitmap file (.BMP). Name the material that refers to the bitmap the same as the bitmap file, without the .BMP suffix. That’s the name the exporter will write out, so it had better be the same.

§ The CMX exporter handles smoothing groups, when calculating vertex normals. Just create smoothing groups as you usually do, and it will do the right thing.

§ It optimizes shared vertex usage, by collapsing vertices that are at the same 3d position with the same texture map coordinate and normal.

o Skills

§ A skill has a beginning and an end in time, and applies to one or more bones of the skeleton.

§ The beginning of a skill is marked by a “beginskill=name” tag on a bone of the skeleton at a certain time, and the end of the skill is marked by an “endskill=name” tag on the same bone at a later time. The names of the beginskill and endskill must match.

§ Full Body skills are attached to the root of the skeleton, and record the animation of the root and all bones below it, unless overridden.

§ Partial Body skills can be attached to a lower bone of the skeleton, and affect that bone and all bones below it, unless overridden.

§ In the same note track key as the “beginskill=name”, you can specify other parameters for the skill.

§ You can override the bones animated by a skill, by listing “includebone=name” and “excludebone=name” tags with the parameters to the beginskill. You can list as many includebone or exclude bone tags as you need, each with different bone names, to specify the bones you want to animate. If you use includebone, the children are not automatically included, so you have to list each one you want. If you use excludebone, the children are automatically included, except for the ones you list. Don’t use includebone and excludebone at the same time, or it might get confused.

§ The “xorigin=value”, “yorigin=value” and “zorigin=value” and “spin=value” tags control the position and orientation of the animation’s coordinate system.

§ The “absolute”, “relative” and “moving” tags mark an animation as being in an absolute coordinate system, a relative coordinate system (starting at the origin), or a moving animation (walking, running or swimming).

§ Events can be delivered to any bone in a skill, at any time between its beginskill and an endskill (inclusive). Events are simply tags that the exporter doesn’t recognize. It removes the tags that it recognizes, inserting the leftover events into the skills to be delivered to the game at run time. Unknown events are simply ignored by the game. See the description of SAnimator to learn about all the different events that are supported.

§ The “skill=name” tag is used to associate the entire note track with a certain skill, so other overlapping skills don’t pick up those events. Not generally very useful or often used.


· Technical Notes

o Requirements for setting 3D Studio Max’s Master Scale, Master Unit Type, Master Unit Scale.

§ You need to set 3D Studio Max’s master unit scale to the right value (feet). Ask Charles for instructions. [TODO…]

o How the CMX Exporter Compiles and optimizes meshes.

§ Describe how the exporter reads weighted vertices, handles texture map coordinate, smoothing groups, computes normal vectors, and optimizes the meshes. [TODO…]

o Texture mapping.

§ Notes related to texture mapping. Where to put the textures, what format to use, how to name the files, how to set up textured materials in Max, and other conventions and constraints. [TODO…]

o Smoothing groups and normals.

§ How to use smoothing groups to create creases and edges, and control the smoothing of polygonal edges. [TODO…]

o Time Scale.

§ How to set up the time scale of the animation. Standard values. [TODO…]

o The CMX Exporter maps new Biped bone names to old bone names. The new version of Character Studio Biped had more medically correct bone names, but we needed to regress to the old names since we still had a lot of old content around. So the CMX Exporter automatically maps new bone names to old bone names, as follows:

§ CALF => LEG1

§ THIGH => LEG

§ UPPERARM => ARM1

§ FOREARM => ARM2

§ CLAVICLE => ARM

o Error messages are reported with offending file names. All the code that could fail reading or writing a file remembers the name of the file in which the error occurred, so the exporter can report more informative error messages. Tools should check for errors and report the problem file names to the user.

o Histogram for tuning compression algorithm.

§ Describe low frequency floating point number compression algorithm. Document how to gather statistics on compression from batch exports, and how to tune the compression algorithm. [TODO…]

o Pose analysis.

§ Document how to gather pose statistics from batch exported animations, and analyze the animation pose statistics, to find glitches and misaligned animations. [TODO…]

o The CMX Exporter write enable flag disables the exporter writing files when false, so you can test a dry run and see what will happen. The exporter uses this internally to generate a list of files that will be modified, to check them out and in to SourceSafe.

o Access Database.

§ Describe how the exporter uses the Access database. Document which fields it depends on, and how they are used. [TODO…]

o Source Safe.

§ Describe how the exporter uses SourceSafe. Document the configuration variables. [TODO…]

· Animation Compiler

o The Animation Compiler reads in batches of un-indexed text animation files, and writes out one FAR file full of indexed binary animations.

§ Describe what the animation compiler does, and how it’s used in the build process. [TODO…]

· File Formats

o CMX files (text vitaboy files)

§ Should phase out vitaboy text files, because of other languages that use comma as a floating point decimal symbol. FaceLift currently writes out text files, as does the exporter. The Animation Compiler translates the text files to binary, and compiles them into a FAR file. FaceLift should use libraries that read and write binary files, and the exporter should write out binary files by default. TODO…

o BCF files (binary vitaboy files)

§ Documented in “SimsFileFormat.txt”.

o SKN files (text DeformableMesh files)

§ Should phase out text files. See note above.

o BMF files (binary DeformableMesh files)

§ Documented in “SimsFileFormat.txt”.

o BIN files (binary uncompressed floating point)

§ Raw binary floating point numbers in Windows format.

o CFP files (binary compressed floating point)

§ Document floating point compression algorithm and file format. [TODO…]

o NDX files (binary vitaboy index file)

§ Index to all CMX files in a FAR file, for pre-loading the cache. Document binary file format, that only appears in FAR files. [TODO…]

o FAR files (archive directories)

§ Archive of files and directories. Document FAR file format. [TODO…]


· Libraries

o Skeleton.cpp

§ Props

· A reference counted property list, containing key/value pairs that are strings.

· PropsAssociation is used internally by Props.

· PropsIterator is an iterator for looping over Props.

§ TimeProps

· A reference counted timeline of Property lists, containing key/value pairs, the keys of which are integers (time), and the values of which are Props (property lists).

· TimePropsAssociation is used internally by TimeProps.

· TimePropsIterator is an iterator for looping over TimeProps.

§ Skeleton

· A reference counted Skeleton keeps track of a list of Bones, threading them into a tree.

· It also manages a vector of Practices that bind Skills to it, and a list of Dressings that bind Suits to it.

· It has a name by which it is known, and a cmxFileName from which it was loaded.

· It has a transform to place it in the world (or group).

· It has a Bone vector, and keeps track of its root Bone. The Bones have pointers to their parents, siblings and children.

· The practicesChanged flag allows the skeleton to efficiently figure out which practices it should apply.

· The void data flag is not currently used.

· The bboxesValid flag and bbox are used to keep track of the bouding box.

§ Bone

· A set of Bones are assembled into a skeletal tree, in a threaded list.

· A Bone represents a translated and rotated coordinate system.

· It has pointers to other parent, sibling and child Bones, which represent the hierarchy through which translation and rotation are inherited.

· Each Bone inherits its parent’s coordinate system, then adds its translation followed by its rotation, to calculate the coordinate system in which the skins are rendered, then passes that transformation on to its children.

· Bones are not reference counted, since the Skeleton manages them.

· Each Bone has a name, as well as a parent name of the bone to which it’s attached.

· It has a (possible NULL) pointer to an optional Props, used to store properties.

· It has a three dimensional vector trans to represent its local translation, and globalTranslation to represent its global translation.

· It has a four dimensional quaternion rot to represent its local rotation, and globalRotation to represent its global rotation.

· It has a transform and a rotMat to keep figure out its transformation to world space.

· It has an integer priority that keeps track of the highest priority opaque practice bound to it, used for optimization.

· It has an extreme flag to control whether it should be used for skeleton bounding box calculation, as well as a bboxValid flag and a bbox, used for calculating its bounding box.

· It has flags canTranslate and canRotate to control whether it supports translation and/or rotation.

· It has a canBlend flag to control whether motions can be blended together on that bone.

· It has a canWiggle flag and wigglePower float to control its Perlin noise QuatNoise wiggler (not currently used). Animations could have events that set the canWiggle and wigglePower values of the bones, to automatically add smooth quaternion Perlin noise to the bones. Needs to be tuned and adjusted to determine the best values to use.

§ Registration

· A Registration has a pointer to a Bone, and a Transform relative to that bone, and it is used to simplify figuring out where to register other 3D objects relative to the skeleton.

§ Skill

· A Skill represents a reference counted named set of Motions that can be applied to the Bones of a Skeleton by creating a Practice.

· It has a name by which it’s called, the fileName of a file containing compressed floating point numbers, the cmxFileName from which it was loaded, the errorFileName to report if something was missing, the resourceSite from which it was loaded, and a loaded flag.

· It contains a vector of Motions, which are bound to bones of a Skeleton by a Dressing.

· It holds all the translations and rotations for the Motions it contains, which are counted in numTranslations and numRotations and stored in translations and rotations.

· It has a duration (the duration of a Practice played at normal speed), a distance (the distance a walking loop should travel forward), an isMoving flag to tell if it’s moving (like a walking loop), an isTurning flag to tell if it’s turning, a 3 dimensional offset to tell how much it moves in 3 dimensions, a quaternion turn to tell how much it turns (not used).

· It keeps track of its activePractices and its lastUnbindTime, so it can automatically unload when it’s not needed.

§ Motion

· A Motion has a Bone name to which it should be bound, as well as a pointer to the Skill that contains it.

· It refers to a particular number of frames of animation data, and has hasRotation and hasTranslation flags, and translationsOffset and rotationsOffset indices into the Skill’s translations and rotations.

§ Practice

· A Practice represents the binding of a Skill to a Skeleton, that associates the Motions of a Skill with the Bones of a Skeleton, and makes a TimePropsIterator for each Motion/Bone binding that has a TimeProps stream of events, so Practice::Apply can read out and handle the events.

· Practices are not reference counted, since they’re managed by a Skeleton.

· A Practice keeps track of the Skeleton and Skills that it binds, as well as a PracticeAssociation vector (each item containing a Bone, a Motion, and a TimePropsIterator for keeping track of events).

· It has a user definable priority that effects the order in which they are applied to the Skeleton.

· It keeps track of the currentTime, the lastTime and the count of frames.

· Its time scale controls how fast it plays. 1.0 is normal speed, 0.5 is half speed, 0.0 is frozen, etc. The duration depends on the scale times the duration of the skill.

· The propsTime and lastPropsTime are used to keep track of event delivery.

· The isOver flag turns to true for the last frame of a Practice.

· The repeatMode controls what the Practice does when it hits the end. Use 0 for hold, 1 for loop, 2 for ping pong, and 3 for fade.

· It can be faded in and out by automatically adjusting its weight, which is controlled by the variables fading, fadeStartTime, fadeDuration, fadeStartWeight and fadeEndWeight.

· It can be flagged as opaque, so it completely covers up lower priority practices. The opaque flag is automatically set when the weight is 1.0.

· The interpolationMode controls how quaternions are blended. Use 0 to snap to the closest quat. Use 1 to quickly compute a weighted average then normalize. Use 2 to SLERP a spherical linear interpolation.

· The skipFrames integer is used to test animations out at lower temporal resolutions, and should normally be 0.

· The stopWhenFaded flag will automatically stop a practice and dispose of it when the fade out is finished.

· The interruptable flag tells if it’s allowed to be interrupted, and can be changed by interruptable events in the event stream.

· The anchor bone points to the toe bone planted on the ground, and the anchored flag tells if it should be anchored.

· The mixRootTranslation and mixRootRotation flags are used to inhibit the mixing of root translations and rotations, to avoid snapping problems.

· The void data pointer isn’t currently used.

§ Suit

· A Suit represents a named set of Skins that can be applied to the Bones of a Skeleton.

· A Suit is reference counted, and automatically unloaded when it has not been used recently.

· It has a name, a cmxFileName to keep track of the name of the CMX file from which it was loaded, an errorFileName to report errors when something is missing, and a resourceSite to keep track of where it was loaded from.

· The type controls whether it is normal (0) or a bouding box (1) not to be drawn but used for censorship.

· It has an optinal Props to associate user defined data.

· It keeps track of its activeDressings and lastUnbindTime, so it can automatically unload when it’s not needed any more.

§ Skin

· A Skin binds a mesh to a bone. Or at least, it used to, when all we had were rigid meshes.

· Actually, now that we have deformable meshes, a Skin just points to a more complicated DeformableMesh, that can attach to a bunch of different bones on its own. The bone of a skin doesn’t matter any more (as long as it exists in the skeleton), because the bone names in the DeformableMesh are the ones actually used.

· It has a Bone name, which must exist, but is otherwise ignored. (If it doesn’t exist, the Skin won’t be dressed onto the Skeleton, but nothing will go wrong).

· It has a name, which is the name of a file containing the actual DeformableMesh data.

· It has some flags, used to control which Skins of a Suit are actually dressed on a Skeleton. This is used by censorship to dress the appropriate subset of the censorship bounding boxes onto the Skeleton. Each skin is marked with a different flag (powers of two), and a mask is passed into Dress to determine which skins should be dressed.

· It has an optional Props, used to store auxiliary information.

· It has a pointer to the Suit that contains it.

§ Dressing

· A Dressing is a reference counted run-time structure created when you dress a Suit on a particular Skeleton. It keeps track of the bindings of the shared Suit’s Skins with the particular Skeleton’s Bones, and indirectly holds other structures needed to draw the character.

· It has a pointer to the Suit and Skeleton that it binds together.

· It has a DressingAssociation vector, each item containing a Skin pointer, a Bone pointer, and a void data pointer (that points to a SkeletonBinding).

· It has a void data pointer, that isn’t currently used.

§ DeformableMesh

· Represents a deformable mesh that can be bound to a skeleton in the game at run-time. It keeps track of its file name, its texture name, the skin that it’s associated with, a vector of bone names, a DeformableFace vector, a BoneBinding vector, a TextureVertex vector, a BlendData vector, and a NormalVertex vector.

§ TextureVertex

· A two-dimensional texture map location, two floating point numbers u and v ranging from 0.0 to 1.0.

§ NakedVertex

· A three-dimensional vertex, three floating point numbers x, y and z.

§ NormalVertex

· A three-dimensional NakedVertex representing the position, with a another three-dimensional NakedVertex representing the normal.

§ BlendData

· Used to keep track of a vertex that’s blended between two bones.

· The weight is an int32 fixed point value (16.16) because of a historical misunderstanding, and should have been floating point (but it doesn’t really matter).

· The otherVert is the index of the other vertex that the BlendedVertex containing this BlendData is to be blended with.

§ DeformableFace

· Represents a triangle, defined by the indices of three vertices, integers a, b and c.

§ BoneBinding

· Keeps track of the binding of rigid and blended DeformableMesh vertices to a bone.

· It refers to the bones, rigid and blended vertices of the DeformableMesh that contains them all.

· It contains the index of the bone to which it binds, the index of the first rigid vertex, the rigid vertex count, the index of the first blended vertex, and the blended vertex count.

§ SkeletonBinding

· Used in the game at run-time, to attach a DeformableMesh to a RenderMesh and an actual skeleton. One SkeletonBinding is created for every Skin of a Suit when you dress a suit on a skeleton, and the Dressing keeps track of it indirectly. It keeps track of a vector of Bones, as well as the bounding box of the mesh on the skeleton.

§ UsedVertex

· Only used by the exporter.

· Keeps track of each time a vertex is used by a face, so it can handle smoothing groups and optimize texture coordinates.

§ BoundVertex

· Only used by the exporter.

· Holds some extra information needed for the sorting and compilation phase, and a UsedVertex vector to keep track of the different faces using this vertex.

§ BlendedVertex

· Only used by the exporter.

· A subclass of BoundVertex that also has a BlendData to keep track of blended vertices.

§ PerlinNoise

· A 1-dimensional Perlin noise generator.

· Used by QuaternionNoise.

§ QuaternionNoise

· A 4-dimensional quaternion Perlin noise generator.


o VitaBoy.cpp

§ Envelope Template

· Used as a wrapper to automatically index, load and unload Skeletons, Skills and Suits, so they can be sorted into a set for fast lookup.

§ VitaRenderGroup

· Subclass of RenderGroup that overrides some of the automatic behavior of IsBoundingBoxDirty, since we’re taking care of that stuff ourselves.

§ VBAnimMgr

· Keeps track of the shared VitaBoy animation data, including Skeletons, Skills, and Suits.

· It uses maps of Envelope templates around all the Skeletons, Suits and Skills.

· It keeps track of the Device3D and the RenderObjectFactory.

· It can load and save animations and indices from text and binary files and streams.

§ VitaBoy

· Wrapper around Skeleton, that knows about device specific stuff, like how to render the Skins with the 3D library.

· Keeps track of the VBAnimMgr, the Device3D, the Skeleton and the RenderGroup.

· Has a realTime flag that’s not used.

· Has a void data pointer that’s used to point to the next higher level of abstraction (SAnimator).

· Has a name, that’s not used.

· Has a rootTransform and rootScale that’s used to place its RenderGroup in the world.

· Has a ghost flag that’s used to draw it transparently.


o SAnimator.cpp

§ DressingRecord

· Used by SAnimator to keep track of Dressings with suit and texture names.

§ HandleVitaBoyAnimEvent

· Event handler that sends events back to the SAnimator buried under several levels of void pointers.

§ SAnimator

· Higher level animation controller, below Person but above VitaBoy.

· Handles mixing and sequencing several parallel layers of animations, dressing suits on the skeleton, walking, and lots of other stuff.

· Sets up search paths for loading animation data.

· Manages strings used to name Skeleton, Suits, etc.

· Resolves Suit and Skill names.

· Has a reference to the containing Person, and to the contained VitaBoy.

· It can start and stop the VitaBoy, and save and restore all the animation state, so it’s possible to stop all the VitaBoys, close down all the animation files, reload them, and start all the VitaBoys back up again.

· Keeps track of Suits for body, head, hands and accessories.

· Keeps track of Outfits

o Normal, Naked, Swim Suit, Job, Formal, Sleep, Skeleton, SkeletonNeg.

· Saves and restores state of Practices and Dressings.

· Keeps track of the location and direction of the person on the grid.

· Plays object and personal animations, and handles and distributes events to tree code.

· Supports walking, running and swimming, with a hairy complex state machine.

· Follows a path created by the router, by sequencing walking and turning animations.

· Handles footstep sound effects.

· Adjusts walking and animation speed according to person’s mood and user’s cursor interactions.

· Handles reaching, carrying, object, personal, background and foreground animations.

· Handles animation events.

o xevt event sends numeric argument to animate primitive false branch.

o interruptable and interruptible events set practice interruptable flag.

o anchor event on bone anchors that bone.

o dress event dresses named suit on skeleton.

o undress event undresses named suit from skeleton.

o lefthand event sets left hand to integer argument.

o righthand event sets right hand to integer argument.

o censor event sets censorship mask.

o sound event plays named sound.

o selectedsound event plays named sound if character is selected.

o delselectedsound event plays named sound if character is not selected.

o footstep event plays footstep, integer argument tells if left or right, but is ignored.

o discontinuity event tells us to expect a snap in root location or rotation, so kill the last practice and don’t blend.

· Handles head faking, to turn the head towards interesting objects and other people.

· Handles rendering and bounding box optimizations so it doesn’t have to draw when off screen.

· Keeps track of Registration Points, used to position held objects, though balloons, and selected person highlight.

o Right Hand, Head, Balloon.

· Anchors feet to reduce moon walking (currently disabled).

· Handles censorship bounding box calculation and rendering.

· Makes snapshots of person’s body.

· Logs animation and walking state events for debugging.

· States

o Animating, Sitting, SittingFloor, Standing, StandingTurn, StandingAdjust, WalkingStart, WalkingStop, WalkingTurn, Walking, Running, RunningStart, RunningStop.

· Popup Head Support

o StartPopupHead, StopPopupHead, StartPopupHeadSubmenu, StopPopupHeadSubmenu, NodPopupHead, GetPopupHeadLocation, RenderPopupHead, SetPopupHeadAttitude.

· Person Picking Support

o PickedPerson, SetPickedPerson, GetPickingPerson, SetPickingPerson.

· Tweakable Class Variables

o gPrintEvents controls if animation events are printed out to ctgDump, for debugging.

o gPinPersonToNextDest is not used.

o gFadeMils controls how long it takes to fade animations out.

o gInterpolationMode controls the interpolation mode of the practices.

o gDoFading controls whether or not we fade practices out.

o gWalkingScale controls the scale that walking animations are played at, by default.

o gWalkingSpeedUp controls how fast walking speeds up, in response to the user pointing at characters.

o gWalkingSlowDown controls how fast walking slows down, in response to the user pointing at characters.

o gStepDistance is the step distance along the path, for route following. It if it’s too small, route following will be inefficient. If it’s too large, route following will cut corners to abruptly.

o gLookAheadDistance is not used.

o gSmallDistance is used to figure out when to play an adjust animation.

o gStopWalkingTurn is used to figure out when to stop walking and turn in place.

o gMaxWalkingTurn is used to limit how much we will turn while walking.

o gSmallTurn is used to figure out if we need to play a standing turn animation.

o gStepTurn is not used.

o gCutOff45Turn is used to figure out when to use the 45 degree turn animation.

o gCutOff90Turn is used to figure out when to use the 90 degree turn animation.

o gCutOff180Turn is used to figure out when to use the 180 degree turn animation.

o gAdjustDistance is not used.

o gMinStopWalkingTime is used to figure out when and how to stop walking.

o gMinStopWalkingDist is used to figure out how close and how to stop walking.

o gMinStopRunningDist is used to figure out how close and how to stop running.

o gMinAdjustWeight is used to limit the weight for adjusting the walk loop animation to stop walking.

o gAnchorFeet is used to turn on and off the foot anchoring behavior.


o CMXExporter.cpp

§ CMXExporter class interfaces to 3D Studio Max, creates Skeletons, Skills and Suits, and exports them to files.

§ MySceneEntry class wraps a 3D Studio Max object, and connects it to the VitaBoy objects that created for export.

o Maxis-MaxScript.ms

§ Implements the user interface to the exporter and the animation database.

§ Control panel has a list of all skills and suits in the database, allowing you to select any of them, automatically load the correct max file fresh from SourceSafe, check the target files out of SourceSafe, and export it to the right directory, and check the target files back into SourceSafe. Also lets you filter them by different criteria, and batch export or verify the things that pass the filter.

§ Animation database is stored in Access. The exporter used to read the animation database directly out of Access via OLE Automation. Now it loads faster cached data from text files of MaxScript code, exported from Access by a macro.

§ Loads and saves user environment variables.

· accessCmd

· sourceSafeDir

· sourceSafeProgDir

· sourceSafeServerDir

· tempDir

· blowingChunks

· chunkSize

· skipToRecord

· processRecords

§ The verbose flag can be set to false to keep the output terse.

§ Batch exports files in chunks to work around Max corruption bug.

§ Integrated with SourceSafe, to get fresh Max files, and check exported files out and back in (or else undo checkout if an error occurred).

§ Compression statistics and histogram analysis and reporting.

§ Pose analysis and reporting.

§ Old unused code for CSM file bone name mapping and ball transplanting, an experiment in mapping a motion capture skeleton to Biped.

§ Old unused code for batch renaming skills.

[Don Hopkins' RadiOMatic BlogUTron]    

Sims Character Animation File Format.

CMX File:
int32 skeletonCount;
Skeleton skeletons[skeletonCount];
int32 suitCount;
Suit suits[suitCount];
int32 skillCount;
Skill skills[skillCount];

Skeleton:
CountedString name;
int32 boneCount;
Bone bones[boneCount];

Bone:
CountedString name;
CountedString parentName;
int32 hasProps;
? Props prop;
float trans[3];
float rot[4];
int32 canTranslate;
int32 canRotate;
int32 canBlend;
int32 canWiggle;
int32 wigglePower;

Skill:
CountedString name;
CountedString fileName; [of CompressedFloatingPoint file]
float duration;
float distance;
int32 isMoving;
int32 numTranslations;
int32 numRotations;
int32 motionCount;
Motion motions[mountCount];

Motion:
CountedString boneName;
int32 frames;
float duration;
int32 hasTranslation;
int32 hasRotation;
int32 translationsOffset;
int32 rotationsOffset;
int32 hasProps;
? Props props;
int32 hasTimeProps;
? TimeProps timeProps;

Suit:
CountedString name;
int32 Type;
int32 hasProps;
? Props prop;
int32 skinCount;
Skin skins[skinCount];

Skin:
CountedString boneName;
CountedString name; [of DeformableMesh file]
int32 flags;
int32 hasProps;
? Props prop;

PropsKeyValue:
CountedString key;
CountedString value;

Props:
int32 size;
PropsKeyValue keyValues[size];

TimePropsKeyValue:
int32 key;
Props value;

TimeProps:
int32 size;
TimePropsKeyValue keyValues[size];

CountedString:
byte len;
(len == 255)
? int32 len;
: char string[len];

DeformableMesh:
CountedString fileName;
CountedString textureName;
int32 boneCount;
CountedString boneNames[boneCount];
int32 faceCount;
DeformableFace faces[faceCount];
int32 boneBindingCount;
BoneBinding boneBindings[boneBindingCount];
int32 textureVertexCount;
TextureVertex textureVertices[textureVertexCount];
int32 blendDataCount;
BlendData blendData[blendDataCount];
int32 vertexCount;
NormalVertex vertices[vertexCount];

DeformableFace:
int aVertexIndex;
int bVertexIndex;
int cVertexIndex;

BoneBinding:
int boneIndex;
int firstVert;

int vertCount;
int firstBlendedVert;
int blendedVertCount;

TextureVertex:
float u;
float v;

BlendData:
int32 weightFixed;
int32 otherVertexIndex;

NakedVertex:
float x;
float y;
float x;

NormalVertex:
NakedVertex naked;
NakedVertex norm;

[Don Hopkins' RadiOMatic BlogUTron]    

Details on The Sims Character Animation File Format and Rendering.

From: "Bil Simser"
To: "Don Hopkins"
Sent: Tuesday, March 21, 2000 7:17 AM
Subject: SKN format

Hi Don,

Is there any way you can just toss me a bone on the SKN files? Just a quick overview? I have most of it but just trying to figure out how the groups are identified. I know it's the 3rd section (after the faces) but not sure what the 4 numbers are for? Can you give me a quick rundown of the file? Thanks.

-Bil

From: "Don Hopkins"
To: "Bil Simser"
Sent: Tuesday, March 21, 2000 12:10 PM
Subject: Re: SKN format

The thing that makes the mesh format weird are the blended vertices, attached to two bones at once. Here are some design documents I wrote, about the Sims file formats, and the animation system. It documents the binary file format, while the cmx files are text, but pretty much equivalent, but maybe missing a few weird fields. It doesn't document the far file format, but I can write that up some time, since it's pretty simple.

-Don

From: "Don Hopkins"
To: "Bil Simser"
Cc: "Don Hopkins"
Sent: Tuesday, March 21, 2000 12:48 PM
Subject: Re: SKN format

What the exporter does, that may not be obvious from the file format, is to figure out from the texture map coordinates and the smoothing groups which vertices to duplicate and collapse.

The exported faces share vertices when possible, but have unique vertices if they're in different smoothing groups. Each vertex it exports (indexed by the faces) also has a normal. So if two adjacent faces are in different smoothing groups, their shared vertices need to have their own normals (calculated by averaging and renormalizing all the normals of the faces in the same smoothing group sharing that vertex), so those shared vertices are duplicated for each unique normal. The blended vertices also have their own normals, that are blended as well.

All the non-blended vertices have their own texture map coordinates too, in a parallel array. The position and normal of each blended vertex is weighted averaged with a non-blended vertex that has its own texture map coordinate, so blended vertices don't need their own texture map coordinates.

If there are any blended vertices (as with bodies but not heads), the blendedDataCount will be greater than zero, and the textureVertexCount will be less than the total vertexCount, in fact: textureVertexCount + blendedDataCount == vertexCount, because the vertices array contains the unblended vertices followed by the blended vertices (each vertex with a normal, i.e. a NormalVertex). The textureVertices array is parallel to the first segment of the vertices array (the rigid vertices), and the blendData array is parallel to the second segment (the blended vertices).

To draw them, you first transform all the vertices[vertexCount] to world coordinates according to the boneBindings, into transformedVertices[vertexCount], then you loop over the blended vertices to blend them with the appropriate other vertices. If i is an index into blendData (from 0 to blendDataCount-1), then i+textureVertexCount is an index into the corresponding blended vertex, and you blend together transformedVertices[i+textureVertexCount] and transformedVertices[blendData[i].otherVertexIndex] (modifying the former one in place, by converting the weightFixed to floating point by dividing by (float)0x00008000 and doing a weighted average to blend together the vertex and the normal, then renormalizing the normal). Then draw the mesh by looping over the DeformableFaces, indexing into the transformedVertices from 0..textureVertexCount-1 and the corresponding texture vertices by the vertex indices in the faces.

I hope that explains those mysterious zeros. (Sorry it's so complicated!)

-Don

From: "Don Hopkins"
To: "Don Hopkins"; "Bil Simser"
Sent: Tuesday, March 21, 2000 1:10 PM
Subject: Re: SKN format

I wrote:

and you blend together transformedVertices[i+textureVertexCount] and transformedVertices[blendData[i].otherVertexIndex] (modifying the former one in place, by converting the weightFixed to floating

Oops I mean "modifying the latter one in place," that is, an optimized version of:

transformedVertices[blendData[i].otherVertexIndex] =
Blend(
transformedVertices[blendData[i].otherVertexIndex],
transformedVertices[i+textureVertexCount],
weight)

where Blend multiplies the first arg by (1.0 - weight) and adds to it the second arg multiplied by weight (then renormalizes the normal).

-Don

[Don Hopkins' RadiOMatic BlogUTron]    

Pepsi and Guinness Can Stove. Via Kevin Kelly's Cool Tools e-zine:



This little stove is amazing; it's made from pepsi and guinness cans, using things that can be found around most households. It takes about an afternoon to make (plus some time waiting for the epoxy to set), weighs only a few grams, and is sufficient for most backpacking trips. I made my first one a few years ago, and I've been handing them out as gifts ever since. The stove is powerful enough to boil a quart of water in a reasonable amount of time, it's MUCH quieter than other camping stoves, if you lose it you're not out $80.00, and you can get the fuel for it (denatured alcohol) at most hardware or paint stores. Mine fits nicely inside of the mug I use for cooking and eating, with room to spare. I usually stuff a spare pair of socks in with it to keep it from rattling around. The site provides detailed instructions and photographs, as well as a message board with feedback and suggestions from other stove builders.

Link to Scott Henderson's Pepsi-G Stove




[Boing Boing Blog]    

Sims Documentation for Third Party Developers.

Here's a design document describing the Sims character animation system and file formats, that have been kicking around the net but never before collected in one place.

Will Wright's original vision (which remains to be fully realized) is to enable storytelling, by allowing players to add their own objects to the game, and encouraging third party developers to create tools and program their own objects. So I wrote this and other documentation to help Sims artists, tool developers and object programmers like Bil Simser, Judson Hudson, Michael Watson, Rick Halle, Tom van Dijk, Dave Baum and Greg Noel, SimSlice, Paladin, MegaSims, Hacker's Resource and SimFreaks.

[Don Hopkins' RadiOMatic BlogUTron]    

© Copyright 2004 William J. Maya.
 

February 2004
Sun Mon Tue Wed Thu Fri Sat
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29            
Jan   Mar


Click here to visit the Radio UserLand website.

Click to see the XML version of this web page.

Subscribe to "a hungry brain" in Radio UserLand.

Click here to send an email to the editor of this weblog.