TTLG|Thief|Bioshock|System Shock|Deus Ex|Mobile
Results 1 to 4 of 4

Thread: Tutorial: Self-Assembling Cabinets With Multiple Doors and Drawers

  1. #1
    Registered: Aug 2007
    Location: LosAngeles: Between Amusements

    Tutorial: Self-Assembling Cabinets With Multiple Doors and Drawers

    This tutorial details the approach I use to make dressers, wardrobes, cabinets, sideboards, and similar furniture items which have multiple individually working doors and drawers.

    The following knowledge and skills are assumed and will not be covered in any detail in this tutorial:
    • Familiarity with basic object modeling and texturing in in some 3D modeling software (Anim8or, Blender, 3dsMax, Maya, etc.)
    • Knowledge of how to model jointed objects for Thief
    • Knowledge of how to model objects with vhots for Thief
    • Knowledge of how to convert your object models from your modeling software's native format into Thief's .bin format and import them into Thief2
    • Knowledge of how to create and save a custom gamesys

    For the purposes of the tutorial I will use a sideboard as an example object. In the real world, a sideboard is a piece of furniture which has doors and drawers that you can open independently, reach inside, and take things out. My goal is to emulate that behavior as closely as possible in the Thief world. The example sideboard has two drawers and two doors, each of which can be frobbed to open individually and each of which can serve as a container when opened (i.e. place some object(s) into the player's inventory) should that be desirable. From the player's perspective, this sideboard functions as a single piece of furniture with working doors and drawers. To accomplish my aim you will actually use 5 separate objects, though they will appear to be a single object to the player:
    1. The sideboard cabinet
    2. The sideboard left drawer
    3. The sideboard right drawer
    4. The sideboard left door
    5. The sideboard right door

    Each of these is modeled and converted into individual .bin objects and assembled in DromEd such that the drawers fit into the drawer spaces in the sideboard cabinet and the doors fit over the door shaped holes in that cabinet. While this assembly can be done by hit or miss tweaking of object positioning in DromEd, it's a bit of a pain, and if you decide later on to move your sideboard it can be a bit tricky to do so. This tutorial will show you an approach to modeling these objects such that they will self-assemble in DromEd for you. I will also cover how you can have appropriate opening and closing sounds for the doors and drawers.

    The following video shows you what we are striving for as an end result.

    <param name="movie" value=";hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src=";hl=en_US" type="application/x-shockwave-flash" width="640" height="480" allowscriptaccess="always" allowfullscreen="true"></embed></object>

    Modeling the Sideboard as 5 Separate Objects
    To begin, model your sideboard cabinet as one object, each drawer as another, and each door (with hinges) as another.

    Click image for larger version. 

Name:	Fig1_cabinet.jpg 
Views:	5 
Size:	228.8 KB 
ID:	1475
    Fig 1. Cabinet without doors and drawers as single object

    Position the doors and drawers such that they align perfectly with the cabinet.

    Click image for larger version. 

Name:	Fig2_cabinet+DDs.jpg 
Views:	8 
Size:	259.8 KB 
ID:	1476
    Fig 2. Cabinet with doors and drawers properly positioned in 3-space

    Because Thief only allows one functioning joint per object, you now need to make each of the doors and drawers into independent jointed objects. The doors will have rotational joints about the center of the hinges and the drawers will have translational joints down the center of the drawers. So we will take each of your properly positioned doors and drawers, and work with them independently, maintaining their location in 3-space for now.

    First the left drawer. To make it into a jointed object it needs to become a sub-object to some base object. For that purpose create a tiny cube at the back of the drawer, and make it fully transparent. Name it Aa. Add an axis for the drawer to slide along down the center of the drawer, and name it @z00Aa0000, and finally, name the drawer itself (which must be a single mesh) @s00Bb. This will give you a drawer that moves in and out when frobbed.

    Click image for larger version. 

Name:	Fig3_left_drawer.jpg 
Views:	12 
Size:	99.5 KB 
ID:	1477
    Fig. 3. Left drawer made into a simple sliding (translating) jointed object

    When we convert the drawer object to .bin, the current 3D positional information will be lost, so we need to capture that and transfer it to the cabinet base. We do this by adding a vhot to the cabinet base, positioned at the location on the cabinet base where we want the centroid of the left drawer to be positioned. This means that we need to figure out where the centroid of the left drawer object is. Remember, the drawer object is not just the drawer itself, but also the little Aa cube. In Anim8or what I do is group the pieces that DromEd will consider when positioning the drawer, Aa and @s00Bb. (DromEd does not use the axis @z00Aa0000 when calculating the drawer's centroid, so neither should we.) I then inspect that group's properties, where Anim8or conveniently displays the x, y, and z of the centroid for that group. I then use that to position a nice new tiny cube which gets named @h00 and textured a nice pure shade of red so that it is visibly distinct from any other geometry. Your 3D modeling program should have some equivalent way for identifying the centroid of that group.

    Click image for larger version. 

Name:	Fig4_left_drawer.+vhot.jpg 
Views:	11 
Size:	209.7 KB 
ID:	1478
    Fig. 4. Left drawer with vhot at its centroid

    Once I have visually assured myself that the vhot is where I expect it to be (i.e. I haven't made a typo in keying in the coordinates or done something else stupid), I cut and past the vhot onto the cabinet object, because that's the object the vhot belongs to. It does not belong to the drawer. I only used the drawer to figure out where the vhot belonged in 3-space.

    Click image for larger version. 

Name:	Fig5_cabinet+h00.jpg 
Views:	5 
Size:	152.0 KB 
ID:	1480
    Fig. 5. Cabinet with vhot @h00 in place

    The right drawer is treated the same way, just with the vhot named @h01.

    The doors are a little different. You need to have the part of the hinges which in real life would attach to the cabinet modeled as a separate mesh from the door itself, with the other half of the hinges modeled as part of the same mesh as the door. This allows you to use the hinges as the base for the door sub-object without the need for a dinky invisible cube the way we needed one for the drawers. And it will look exactly right in Thief when the door opens, with half of the hinges fixed to the cabinet and the other half pivoting on the door. So, the half hinges get named Aa, the axis gets named @x00Aa0000 (x because it is a rotational joint), and the door named @s00Bb.

    Click image for larger version. 

Name:	Fig6_right_door.jpg 
Views:	9 
Size:	88.0 KB 
ID:	1479
    Fig. 6. Right side door with base, Aa, highlighted

    The left side door is constructed in the same manner, and you create and position the vhots in the same way as for the drawers, naming the left door's vhot @h02 and the right door's vhot @h03, and then move them to the cabinet object.

    Click image for larger version. 

Name:	Fig7_cabinet+vhots.jpg 
Views:	4 
Size:	117.6 KB 
ID:	1481
    Fig 7. Cabinet with 4 vhots in place

    Status Check
    The cabinet object now has 4 vhots, @h00, @h01, @h02, and @h03. The doors and the drawers are individual jointed objects. So you are now ready to convert them all to .bin files by your usual method.

    The attached .zip contains .3ds, .bin, textures, and sample (1.19) .mis. .gam, and .cow files for my example sideboard so that you can follow along in DromEd and/or just take a look and see what I did to set this up.

    DromEd Hierarchy Work
    You need to create some new archetypes to support your self-assembling sideboard.

    Open up the Object Hierarchy and navigate to Furniture > Tables (-3573). Add a new object archetype named Sideboard as a child of Tables.

    Next navigate to Container > Chest (-2571). Add a new object archetype named SideboardLdoor as a child of Chest and another new object archetype named SideboardRdoor as a child of SideboardLdoor.

    Similarly add a new object archetype named SideboardLdrawer as a child of Chest and another new object archetype named SideboardRdrawer as a child of SideboardLdrawer.

    1. Open the Sideboard archetype
    Shape > Model name: SBDLxmpl

    2. Open the SideboardLdoor archetype.
    Shape > Model name: SBDLxmpl
    Schema > Class tags: BoxType BoxMoney
    SFX > Particles: {TRUE; Single-colored pixels; Launched continually; Attached to object ... (leave the rest at the defaults)}
    Links > ParticleAttachment: {From: SideboardLdoor; To: Sideboard; Type: Vhot; vhot #:2}
    Click image for larger version. 

Name:	Fig8_DoorJoints.jpg 
Views:	3 
Size:	64.0 KB 
ID:	1482Click image for larger version. 

Name:	Fig8_DoorJointsState.jpg 
Views:	119 
Size:	25.4 KB 
ID:	1483
    Fig 8. Door joints tweq

    3. Open the SideboardRdoor archetype.
    Shape > Model name: SBDRxmpl
    Links > ParticleAttachment: {From: SideboardRdoor; To: Sideboard; Type: Vhot; vhot #:3}

    4. Now open the SideboardLdrawer archetype.
    Shape > Model name: SBDwLxmpl
    SFX > Particles: {TRUE; Single-colored pixels; Launched continually; Attached to object ... (leave the rest at the defaults)}
    Links > ParticleAttachment: {From: SideboardLdrawer; To: Sideboard; Type: Vhot; vhot #:0}
    Click image for larger version. 

Name:	Fig9_DrawerJoints.jpg 
Views:	3 
Size:	64.1 KB 
ID:	1484Click image for larger version. 

Name:	Fig8_DoorJointsState.jpg 
Views:	119 
Size:	25.4 KB 
ID:	1483
    Fig 9. Drawer joints tweq

    5. Open the SideboardRdrawer archetype.
    Shape > Model name: SBDwRxmpl
    Links > ParticleAttachment: {From: SideboardRdoor; To: Sideboard; Type: Vhot; vhot #:1}

    Status Check
    You have created 5 archetypes: the sideboard, its 2 drawers and its 2 doors. The doors and drawers are given particle properties so that they can be ParticleAttached to the sideboard via its vhots. The doors and drawers also have their joint properties established. Finally the doors and drawers inherit from the Container archetype, so if you establish a Contains link from them to a loot object, say, that loot object will be given to the player when the door or drawer is frobbed open. All that's left to do is to place the sideboard in your mission (and save the gamesys, but you have been doing that periodically while following along with the tutorial, yes?).

    Note: In this tutorial I reused the opening and closing sounds from the money box and the chest. You could make custom opening and closing sounds for your drawers and doors, but that's another tutorial.

    If you find that you missed placing the vhots exactly right, just tweak them appropriately in your modeler and regenerate the sideboard bin file. Restart DromEd, place a new sideboard and verify that everything is OK. Once you have it to your satisfaction you can just place the sideboard, and the doors and drawers will take care of themselves. Have fun.

    Note: Thanks to NV for discovering that you can fool Dark into thinking that something is a particle when it's not and then use a ParticleAttachment link. At least that's to whom I've seen the idea attributed.
    Attached Files
    Last edited by LarryG; 30th Oct 2012 at 00:29. Reason: typos & grammar

  2. #2
    Registered: Apr 2001
    Location: Lost in the BSP...

    The skill level evident in some of the current side-projects of Thief simply amaze me. That's some nice work, LarryG. You make it look so "simple".

    I had always thought it was possible, it just needed someone with the necessary skills in a 3D modeling program and Dromed to make it happen. I have a feeling we'll be seeing a lot of these in FMs, since that was one type of thing sorely missing in the Thief universe.

    Don't suppose you've seen any custom trees around here....? I'm looking for an oak. Still.

  3. #3
    Registered: Jun 2008
    Location: Germany

    very nice tutorial, Larry.
    it would like to add some ideas for anyone that wants to build things like that.

    cigar box hinge
    cigar box hinge 2
    cigar box hinge 3
    wooden box accessories 1
    wooden box accessories 2
    cigar box corner pieces

  4. #4
    Registered: Jan 2012
    Location: Gèrmany
    Really nice tutorial. Thank you very much.

    But there is one thing I want to add:
    Opening/Closing 2 or more joints at the same time - uses NVScript 1.2.3

    With the NVScript 1.2.3 NamelessVoice provided a script I really looked forward to it's the
    NVJointControl script. It allows you to to open 2 or more joints at once. And also closing them again is possible.

    1)Load NVScript: command: load_script nvscript
    2) Open the archtype of you object
    (->If it or the archtypes above don't have a Tweq - Joints option do
    (-> Add -> Tweq -> Joints
    -- Change Halt to Stop Tweq
    -- Set AnimC to Sim
    --Optional: Define your joint movement data X=Speed, Z=Movement(distance or degree)
    If you don't define it now or want to change it you can do that in the DesignNote see below.

    -> Add -> S -> Scripts
    ----Delete whats written there, write
    ----'NVScriptControl' into Script0 (Without ')
    ----'NVRelayTrap' into Script1
    -> Add -> Editor -> DesignNote
    Copy these lines into the DesignNote
    Play with the blue and cyan values until everything moves right.
    To add additional joints write NVJointControlOn1Joint3=45 and so on.


    Now everything should move and rotate around.


    Further explenation:
    "FrobWorldEnd" This is simply said a rightclick when the object is highlighted. Use "TurnOn" (with " !!) if you want to do it via a switch. The way I wrote this it will close with every TurnOff and every second right click(because first click is opening).

    Joint#: This is the actual joint number

    1Joint1=90 or =0.5, depending if it's an rotating or translating joint this number describes either the rotation in degree or the distance to travel. Equivalent to Z in the tweq options
    In 2Joint# it's set to 0 = means standard position

    Joint1Speed=15 or 0.1 Equivalent to X in the tweq options. This number tells the joint how fast it has to move in for rotation use bigger values. Try it out. Max Value / (2 or 3 or 4) are good values. For closing 2Joint# you can also define other values.

    On1: All joints with such a 1 will do their action on the command specified by On1="FrobWorldEnd" all with 2 on CloseMe

    If you are itnerested in which other ways you can use this script -> check Here
    Last edited by Daraan; 29th Oct 2012 at 16:31.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts