User:Ferrofluidd/Sandbox

From Toontown Corporate Clash Wiki
Jump to navigation Jump to search

Models cannot be altered through the use of Content Packs, but can still be exported and viewed. By doing so, you can view things such as a models different parts and animations. Models can be viewed by either using Panda3D itself, another program capable of running the language Python, or altering the file type to be usable in an alternative program such as Blender.

Loading Models with Python

If you want to go beyond just viewing the models with Panda3D, you must first install a program that can run Python code. You will also need to have Python installed if it isn't already. The version of Python you are using must match the version of Panda3D you are using. When downloading Panda3D, it downloads Python as well if selected. The program that this tutorial will primarily use is Geany.

Before dabbling with models, it is recommended to first extract all of the models and map files (textures) from every phase file. After extracting, move the folders to your Panda3D folder, this ensures that there won't be any missing texture issues later on. The Panda3D folder should be in your main drive (typically the C: drive) labelled Panda3D(version number). They do not need to be placed into another folder or any folders inside the Panda3D folder.

Model Directories

Phase 3
  • Toon Head Models
  • Toon Body Models
  • Make a Toon Room Model
Phase 3.5
  • Toon Hall
  • Cog Body Models
  • Schoolhouse
  • Miscellaneous Props
  • SuitC Animations
  • Toon Animations
Phase 4
  • Fish Models
  • SuitA Animations
  • SuitB Animations
  • SuitC Animations
  • Toon Animations
  • Miscellaneous Props
Phase 5
  • SuitA Animations
  • SuitB Animations
  • SuitC Animations
  • Gags
  • Skelecog Models
  • Skelecog Skulls
  • Skelecog Skull Animations
  • Field Office Model
  • Cog Buildings
  • Toon Battle Animations
Phase 5.5
  • Estates
  • Furniture
Phase 6
  • Acorn Acres
    • Chainsaw Consultant Building
  • Barnacle Boatyard
    • Rainmaker Pier
  • Mezzo Melodyland
    • Major Player Building
  • Roadster Raceway
  • Minigames Area
  • Golf
  • Race Karts
  • Toon Golf Animations
Phase 7
  • Ye Olde Toontowne
  • Cog Building Interiors
  • SuitA Fountain Pen Animation
Phase 8
  • Daffodil Gardens
  • The Brrrgh
    • Plutocrat Building
  • Drowsy Dreamland
    • Pacesetter Building
  • SuitA Song and Dance Animation
  • SuitA Cigar Smoke Animation
Phase 9
  • Sellbot HQ
    • Sellbot Factory
    • Multislacker Building
  • VP Head
  • Sellbot Heads
  • Pacesetter Animations
  • Multislacker Animations
  • Goons
Phase 10
  • Cashbot HQ
  • CFO Head
  • Cashbot Heads
  • Plutocrat Animations
  • Duck Shuffler Animations
  • SuitA Defense Animation
Phase 11
  • Lawbot HQ
  • CLO Head
  • Lawbot Heads
  • Litigation Team Animations
Phase 12
  • Bossbot HQ
  • CEO Head
  • Bossbot Heads
  • High Roller Head
  • Chainsaw Consultant Animations
  • High Roller Animations
  • Featherbedder Animations
  • Firestarter Animations
Phase 13
  • Events
Phase 14
  • Boardbot Heads
  • Deep Diver Animations
  • Head Honcho Cigar Smoke

*Note: Certain files are not in their "typical" location, so depending on what you are looking for it may be in an alternate phase file. I.e. Manager cheat animations being in phase 5 rather than their respective department phase files.

Cogs

This first tutorial will give directions on how to build and see animations for a Cog's model. Cog models are built by combining unique head models to a variety of different bodies.

First, open Geany and create a new file and save it as a .py file. This can be done by simply adding .py at the end of the file name. After that, you will then import the needed "imports" to make model viewing possible. Paste the following code at the very top of the file:

from direct.actor.Actor import Actor
from direct.showbase.ShowBase import ShowBase
base = ShowBase()


This code is just telling the program what you would like to do (view models) and providing the base commands for viewing them. After you've added the code you will then add the camera. This will be inserted at the very bottom:

base.oobe()
camera.hide()
base.run()


When loading the model, in order for it to appear without jagged edges, Anti-Aliasing must be turned on. To do this, first add the following to the TOP of the file alongside the other imports:

from panda3d.core import AntialiasAttrib


Next, add the following towards the bottom above the previous lines.

render.setAntialias(AntialiasAttrib.MMultisample)


In order for it to turn on, two additional lines of text need to be added to Panda3D's config folder. Open the folder for Panda3D, go to the folder Etc, open Config.prc in any text editing app, and add this to the bottom and save:

framebuffer-multisample 1
multisamples 24


Note: All code should only be inserted between the imports and base.run().


Before starting, for some quality of life changes, the background color when loading a model can be changed. Simply add the following to the middle section of the code:

base.setBackgroundColor(0,1,0)


The number values are in order of RGB, so they can be adjusted to any color. The example has the background set to green.

Let's now load a model. For simplicity's sake, we will load the buff Cog body model. First, define a variable and call it Model. Next, we can make it an "actor" in order to allow for animations to be applied to it. The model for the buff Cog body is located in phase_3.5, under models, then "char". The buff Cog model is named "suitA-mod.bam". Since this model is an actor, we can apply the neutral Cog animation to it. This specific animation can be found in phase_4. Animations are located in the same folder as the models. Let's also make it loop the animation we've added to the actor. Make sure to also re-parent the variable (the model) to render, to make Panda3D actually render the actor.

Model = Actor('phase_3.5/models/char/suitA-mod.bam', {'Animation': 'phase_4/models/char/suitA-neutral.bam'})
Model.loop('Animation')
Model.reparentTo(render)
Model.setH(180)


You can run this code to test if it is working correctly by pressing the gear icon at the top of the ribbon in Geany. A Panda3D window should open with the Cog body loaded and animated. If an error appears stating that there is no module named "direct" you will need to change your build settings. You can do this in Geany by clicking the down arrow next to "build" in the ribbon (brick icon). If you look at the bottom you should see an execute command and "py "%f"". Replace that text with your Panda3D folder location\python\ppython.exe %f. It will look something like this:

C:\Panda3D-1.10.13-x64\python\ppython.exe %f

Once the model has loaded, you should see the buff Cog body. The tie won't look quite right, but this will be dealt with later on. The camera can be adjusted by using your scroll wheel to turn the model around, right click to zoom in and out, and left click to move the position of the camera. Since this is only the body, let's add a head. For this tutorial, we will use the Major Player's head model. His head can be located in phase_12, under "char", then "suits". You can add this code directly under the code that was used to load the body:

Head = Actor('phase_12/models/char/suits/ttcc_ene_majorplayer-zero.bam', {'HeadAnimation': 'phase_12/models/char/suits/ttcc_ene_majorplayer-neutral.bam'})
Head.loop('HeadAnimation')
Head.reparentTo(Model.find('**/joint_head'))


Now if you run the code, you will see the head is animated and is attached to the body. Let's now fix the "tie" issue, where both the normal tie and bow tie are both present. The code below will hide both the bowtie and necktie. Simply omit (by adding a # at the beginning of the line of code you're omitting) the correct code to get the results you want:

Model.find('**/bowtie').hide() #Omit this for bowties
Model.find('**/necktie-s').hide() #Omit this for neckties
Model.find('**/necktie-w').hide()


Both neckties need to be hidden for only the bowtie to appear. If you want only neckties, you can either omit both or one. For this instance, the Major Player, the lines of code hiding the neckties needs to be omitted.

Let's now move on to textures. Loading and applying textures is relatively simple. Let's try loading in the Major Player's suit texture for our example. This line of code tells the program to use his textures when loading other parts of his body:

SuitTexture = loader.loadTexture('phase_12/maps/ttcc_ene_suittex_mplayer.png')


After that, let's apply the texture to the Cog model's body, necktie, and bowtie. After running this code the Major Player's suit texture should be applied:

Model.find('**/body').setTexture(SuitTexture,1)
Model.find('**/bowtie').setTexture(SuitTexture,1)
Model.find('**/necktie-s').setTexture(SuitTexture,1)
Model.find('**/necktie-w').setTexture(SuitTexture,1)


Let's now load in the Cog's emblem.

Emblem = loader.loadModel('phase_3.5/models/char/ttcc_ene_insignias.bam')
Emblem.reparentTo(Model.find('**/joint_attachMeter'))
Emblem.setH(180)


If you want the emblem to show the Cog's department, input the following code. This code will hide the HP texture, which will instead show the department icons. To change it to a specific department, hide all other departments except the department you're setting it by omitting the line similar to the bowties and neckties. Sales is Sellbot, Legal is Lawbot, Money is Cashbot, Board is Boardbot, and Corp is Bossbot. This example code already has the hidden Bossbot texture omitted:

Emblem.find('**/emblem_hp').hide()
Emblem.find('**/emblem_sales').hide()
Emblem.find('**/emblem_legal').hide()
Emblem.find('**/emblem_money').hide()
Emblem.find('**/emblem_board').hide()
#Emblem.find('**/emblem_corp').hide()


If after adding the emblem, the textures do not appear, add the following line:

EmblemTexture = loader.loadTexture('phase_3/maps/ttcc_suit_insignias_palette.png')
Emblem.setTexture(EmblemTexture, 1)


Let's now move on to colors. When loading a Cog body model the hands will always default to white. For the Major Player, this is correct, but for most other Cogs it is not. You can find the correct color by color picking an image of the Cog and entering it into the code. However, Panda3D does not use normal RGB. Instead, it uses floating-point values ranging from 0 to 1. To get accuracy colors, first get the RGB values of the wanted color and then divide it by 255. For this example, we will change the Major Player's hand color to match his head color:

Model.find('**/hands').setColor(0.56, 0.48, 0.39)


Congratulations! You have successfully loaded in the Major Player!

The final code should look like this:

Show More

from panda3d.core import AntialiasAttrib
from direct.actor.Actor import Actor
from direct.showbase.ShowBase import ShowBase
base = ShowBase()

Model = Actor('phase_3.5/models/char/suitA-mod.bam', {'Animation': 'phase_4/models/char/suitA-neutral.bam'})
Model.loop('Animation')
Model.reparentTo(render)
Model.setH(180)
Head = Actor('phase_12/models/char/suits/ttcc_ene_majorplayer-zero.bam', {'HeadAnimation': 'phase_12/models/char/suits/ttcc_ene_majorplayer-neutral.bam'})
Head.loop('HeadAnimation')
Head.reparentTo(Model.find('**/joint_head'))
Model.find('**/bowtie').hide()
# Model.find('**/necktie-s').hide()
Model.find('**/necktie-w').hide()
SuitTexture = loader.loadTexture('phase_12/maps/ttcc_ene_suittex_mplayer.png')
Model.find('**/body').setTexture(SuitTexture, 1)
Model.find('**/bowtie').setTexture(SuitTexture, 1)
Model.find('**/necktie-s').setTexture(SuitTexture, 1)
Model.find('**/necktie-w').setTexture(SuitTexture, 1)
Emblem = loader.loadModel('phase_3.5/models/char/ttcc_ene_insignias.bam')
Emblem.reparentTo(Model.find('**/joint_attachMeter'))
Emblem.setH(180)
Emblem.find('**/emblem_hp').hide()
Emblem.find('**/emblem_sales').hide()
Emblem.find('**/emblem_legal').hide()
Emblem.find('**/emblem_money').hide()
Emblem.find('**/emblem_board').hide()
#Emblem.find('**/emblem_corp').hide()
EmblemTexture = loader.loadTexture('phase_3/maps/ttcc_suit_insignias_palette.png')
Emblem.setTexture(EmblemTexture, 1)
Model.find('**/hands').setColor(0.56, 0.48, 0.39)

render.setAntialias(AntialiasAttrib.MMultisample)
base.oobe()
camera.hide()
base.run()

Screenshots

Additional panels can be added to easily view the model's animation frames, easily adjust the position of the model, and various other features. This will be important when taking screenshots. The purpose of taking screenshots this way is to provide a transparent background to the images, giving a cleaner appearance. Starting at the top of the page with the other imports:

from direct.tkpanels import *
from direct.tkpanels.AnimPanel import ActorControl, AnimPanel


Add this above the code for the camera (base.oobe):

ap=AnimPanel([Model, Head])
base.accept('p', base.screenshot)
Model.place()


Note that in this example, "p" is the key that will be pressed in order to take a screenshot. This can be adjusted to any key.

Finally, for this to all function, open your Panda3D folder, open the etc folder, open Config.prc with any text editing application, and add screenshot-extension png to the bottom of the file and save. When screenshots are taken they will be saved in whichever folder the Geany file is placed in. If you do not want the RGB placer (the thing at the feet of the model) visible in the screenshots, adjust the Cogs position using the Place Panel to be away from it.

If you followed the previous tutorial, and then this tutorial, the final code should look like this:

Show More

from panda3d.core import AntialiasAttrib
from direct.tkpanels import *
from direct.tkpanels.AnimPanel import ActorControl, AnimPanel 
from direct.actor.Actor import Actor
from direct.showbase.ShowBase import ShowBase
base = ShowBase()

Model = Actor('phase_3.5/models/char/suitA-mod.bam', {'Animation': 'phase_4/models/char/suitA-neutral.bam'})
Model.loop('Animation')
Model.reparentTo(render)
Model.setH(180)
Head = Actor('phase_12/models/char/suits/ttcc_ene_majorplayer-zero.bam', {'HeadAnimation': 'phase_12/models/char/suits/ttcc_ene_majorplayer-neutral.bam'})
Head.loop('HeadAnimation')
Head.reparentTo(Model.find('**/joint_head'))
Model.find('**/bowtie').hide()
# Model.find('**/necktie-s').hide()
Model.find('**/necktie-w').hide()
SuitTexture = loader.loadTexture('phase_12/maps/ttcc_ene_suittex_mplayer.png')
Model.find('**/body').setTexture(SuitTexture, 1)
Model.find('**/bowtie').setTexture(SuitTexture, 1)
Model.find('**/necktie-s').setTexture(SuitTexture, 1)
Model.find('**/necktie-w').setTexture(SuitTexture, 1)
Emblem = loader.loadModel('phase_3.5/models/char/ttcc_ene_insignias.bam')
Emblem.reparentTo(Model.find('**/joint_attachMeter'))
Emblem.setH(180)
Emblem.find('**/emblem_hp').hide()
Emblem.find('**/emblem_sales').hide()
Emblem.find('**/emblem_legal').hide()
Emblem.find('**/emblem_money').hide()
Emblem.find('**/emblem_board').hide()
#Emblem.find('**/emblem_corp').hide()
EmblemTexture = loader.loadTexture('phase_3/maps/ttcc_suit_insignias_palette.png')
Emblem.setTexture(EmblemTexture, 1)
Model.find('**/hands').setColor(0.56, 0.48, 0.39)

render.setAntialias(AntialiasAttrib.MMultisample)
base.setBackgroundColor(0,1,0)
ap=AnimPanel([Model, Head])
base.accept('p', base.screenshot)
Model.place()
base.oobe()
camera.hide()
base.run()

Miscellaneous

Some models are a bit unique and have some features that require additional lines of code. For example, the Chainsaw Consultant and the Scapegoat require you to turn on backface culling. Without this turned on, the Chainsaw Consultant's saw will only be one sided and the Scapegoat's ear will be backwards. To fix this, add the line: render.setTwoSided(True). The Witch Hunter's head model is also a bit smaller than it should be compared to how it is in game. To adjust the size, add the line: Head.setScale(1.25). For other Cogs with different sized heads, adjust the number value at the end to match. The Cog Gallery is a good reference for viewing Cog sizes.

Additionally, due to how the Rainmaker's textures are set up, in order to change the weather of her hair a specific code needs to written. Change "offset" to one of the listed numbers to choose which weather phase to have visible.

for Hair in Head.findAllTextureStages("*hair"):
    Head.setTexOffset(Hair, 0, 0.2)
# Modify the second number to set the texture
# 0 - inversion, 0.2 - heavy rain, 0.4 - oil rain, 0.6 - storm cell, 0.8 - fog


There is also currently no known way to set the Duck Shuffler's slot position with the model from the phase files, although an edited model can be used for that purpose. This also requires specific code, similar to the Rainmaker.

Patched Duck Shuffler head (bam model)

Patched Duck Shuffler head (egg source code)

for Hair in Head.findAllTextureStages("slot1"):
    Head.setTexOffset(Hair, 0, 0.25)
# Modify the string to set the texture name
# slot1 - left slot, slot2 - middle slot, slot3 - right slot
# Modify the second number to set the texture
# 0 - sevens, 0.25 - ducks, 0.5 - bar, 0.75 - cherry