FANDOM


programmed with: Panda3D 1.8.1, Python 2.7.3, Notepad, and various online tutorials and resources.
picture saving/editing software: MS Paint and Photoshop CS3.


Panda3D_Dog_Tut_v7_pub1.py


#started 2017_09_25_September
#last big change to code before 2017_10_15_October
#simplified 2019_03_20_March for public release

#https://www.reddit.com/r/Toontown/comments/54mpfh/toontown_toon_model_export_with_clothes/
#http://xdar1d.tumblr.com/post/83997644958/panda3d-dog-tutorial-pype

#Placement and scale of hat, glasses, and backpack by me, Dyna/[REDACTED]. May not be 100% accurate to the game.


#Dog
from direct.actor.Actor import Actor
from pandac.PandaModules import *
from direct.task import Task
import math
from math import pi, sin, cos
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from direct.interval.IntervalGlobal import Sequence
from pandac.PandaModules import Point3
from pandac.PandaModules import *

import direct.directbase.DirectStart
from panda3d.core import CollisionTraverser,CollisionNode
from panda3d.core import CollisionHandlerQueue,CollisionRay
from panda3d.core import Filename,AmbientLight,DirectionalLight
from panda3d.core import PandaNode,NodePath,Camera,TextNode
from panda3d.core import Vec3,Vec4,BitMask32
from direct.gui.OnscreenText import OnscreenText
from direct.actor.Actor import Actor
from direct.showbase.DirectObject import DirectObject
import direct.directbase.DirectStart
from panda3d.core import ColorAttrib

#from panda3d.core import loadPrcFileData
#loadPrcFileData("", "interpolate-frames 1")

#https://github.com/Ed-von-Schleck/panda3d/blob/master/direct/src/showbase/ShadowDemo.py

dog = Actor(


#Dog Actor

#Head (Don't change skirt to head even if it's a boy, only applies to dog toons)
{"head":"phase_3/models/char/tt_a_chr_dgm_skirt_head_1000.bam",

#Torso
#To change the size of the Torso, here are the sizes you can choose from:
#Small = "dgs", Medium = "dgm", Long/Tall: "dgl"
#Replace "dgl" with what size you want.
#If you want a boy toon, replace "skirt" with "shorts".

"torso":"phase_3/models/char/tt_a_chr_dgm_shorts_torso_1000.bam",


#Legs
#To change the size of the legs, repeat the same thing as before:
#Short = "dgs", Medium = "dgm", Tall = "dgl"
#Replace "dgm" with what size you want
#If you want a girl toon, you don't need to change the "shorts" to "skirt", it's the same thing.
"legs":"phase_3/models/char/tt_a_chr_dgm_shorts_legs_1000.bam",

},

#dog.shadow.setSx(0.5)
#dog.find('**/torso-top')
#.setScale(0.25, 0.25, 0.25)

#Animations

#Make sure the torso size, and legs are the same as the Actor (Dog)
#{"head":{"run":"phase_3.5/models/char/tt_a_chr_dgm_skirt_head_jump-zhang.bam"},
#"torso":{"run":"phase_3.5/models/char/tt_a_chr_dgm_shorts_torso_jump-zhang.bam"},
#"legs":{"run":"phase_3.5/models/char/tt_a_chr_dgm_shorts_legs_jump-zhang.bam"}})

#{"head":{"run":"phase_3.5/models/char/tt_a_chr_dgm_skirt_head_victory-dance.bam"},
#"torso":{"run":"phase_3.5/models/char/tt_a_chr_dgm_shorts_torso_victory-dance.bam"},
#"legs":{"run":"phase_3.5/models/char/tt_a_chr_dgm_shorts_legs_victory-dance.bam"}})

#{"head":{"run":"phase_3.5/models/char/tt_a_chr_dgm_skirt_head_teleport.bam"},
#"torso":{"run":"phase_3.5/models/char/tt_a_chr_dgm_shorts_torso_teleport.bam"},
#"legs":{"run":"phase_3.5/models/char/tt_a_chr_dgm_shorts_legs_teleport.bam"}})

{"head":{"run":"phase_3/models/char/tt_a_chr_dgm_skirt_head_run.bam"},
"torso":{"run":"phase_3/models/char/tt_a_chr_dgm_shorts_torso_run.bam"},
"legs":{"run":"phase_3/models/char/tt_a_chr_dgm_shorts_legs_run.bam"}})

#{"head":{"run":"phase_3/models/char/tt_a_chr_dgm_skirt_head_neutral.bam"},
#"torso":{"run":"phase_3/models/char/tt_a_chr_dgm_shorts_torso_neutral.bam"},
#"legs":{"run":"phase_3/models/char/tt_a_chr_dgm_shorts_legs_neutral.bam"}})

#{"head":{"run":"phase_9/models/char/tt_a_chr_dgm_skirt_head_push.bam"},
#"torso":{"run":"phase_9/models/char/tt_a_chr_dgm_shorts_torso_push.bam"},
#"legs":{"run":"phase_9/models/char/tt_a_chr_dgm_shorts_legs_push.bam"}})

#{"head":{"run":"phase_3.5/models/char/tt_a_chr_dgm_skirt_head_jump-z.bam"},
#"torso":{"run":"phase_3.5/models/char/tt_a_chr_dgm_shorts_torso_jump-z.bam"},
#"legs":{"run":"phase_3.5/models/char/tt_a_chr_dgm_shorts_legs_jump-z.bam"}})

#{"head":{"run":"tto/phase_4/models/char/tt_a_chr_dgm_skirt_head_periscope.bam"},
#"torso":{"run":"tto/phase_4/models/char/tt_a_chr_dgm_shorts_torso_periscope.bam"},
#"legs":{"run":"tto/phase_4/models/char/tt_a_chr_dgm_shorts_legs_periscope.bam"}})

#Attach the parts
dog.attach("head", "torso", "def_head")
dog.attach("torso", "legs", "joint_hips")
#dog.attach("shadow", "legs", "joint_shadow")


#loadPrcFileData("run", "interpolate-frames 1")

#Loop Animation
#dog.loop('run', 'torso')
#dog.loop('run', 'legs')
dog.loop('run')

#Render
dog.reparentTo(render)

#Eyelashes (If you want a girl dog add this entire code)
#eyelashes = loader.loadModel ('phase_3/models/char/dog-lashes.bam')
#eyes = dog.find('**/eyes')
#eyelashes.find('**/closed-long').removeNode()
#eyelashes.find('**/closed-short').removeNode()
#eyelashes.find('**/open-long')
#eyelashes.find('**/open-short').removeNode()
#eyelashes.reparentTo(eyes)


#Find Parts
feet = dog.find('**/feet') #add .removeNode() if you want shoes, if not keep it like it is
legs = dog.find('**/legs')
neck = dog.find('**/neck')
arms = dog.find('**/arms')
head = dog.find('**/head')
backhead = dog.find('**/head-front')

#Set Glove Color
hands = dog.find('**/hands').setColor(1, 1, 1, 1)

#Load Clothing Textures
dog.shirt = loader.loadTexture ("phase_3/maps/desat_shirt_5.jpg")
dog.sleeves = loader.loadTexture ("phase_3/maps/desat_sleeve_5.jpg")
dog.shorts = loader.loadTexture ("phase_3/maps/desat_shorts_8.jpg") 

#desat_shirt_5.jpg
#desat_sleeve_5.jpg
#CowboyShirt4.jpg
#CowboySleeve4.jpg

#Set Clothing Textures
shirt = dog.find('**/torso-top').setTexture(dog.shirt, 1)
sleeves = dog.find('**/sleeves').setTexture(dog.sleeves, 1)
shorts = dog.find('**/torso-bot').setTexture(dog.shorts, 1)

#If you'd like to change colors for clothing if you use different clothes use something like this for example:
#Set Clothing Color
shirt = dog.find('**/torso-top').setColor(0.460938, 0.378906, 0.824219, 1.0)
sleeves = dog.find('**/sleeves').setColor(0.460938, 0.378906, 0.824219, 1.0)
# shorts = dog.find('**/torso-bot').setColor(0.863281, 0.40625, 0.417969, 1.0)

#Remove Shoes/Boots (If you want shoes, remember to remove the #'s:

shoes = loader.loadTexture ("phase_4/maps/tt_t_chr_avt_acc_sho_converseStyleBlack.jpg")
#dog.find('**/boots_long').removeNode()
#dog.find('**/shoes').removeNode()
#dog.find('**/boots_short')
dog.find('**/boots_short').setTexture(shoes, 1)

#If you add the shoes, remove the feet so go back up and put ".removeNode()" after the feet so it will be: 
feet = dog.find('**/feet').removeNode()
#keep this if you want no shoes
#dog.find('**/boots_short').removeNode()
dog.find('**/shoes').removeNode()
dog.find('**/boots_long').removeNode()

#Toon Color

#Here's the toon colors:
#White (1.0, 1.0, 1.0, 1.0)
#Peach (0.96875, 0.691406, 0.699219, 1.0)
#Bright Red (0.933594, 0.265625, 0.28125, 1.0)
#Red (0.863281, 0.40625, 0.417969, 1.0)
#Maroon (0.710938, 0.234375, 0.4375, 1.0)
#Sienna (0.570312, 0.449219, 0.164062, 1.0)
#Brown (0.640625, 0.355469, 0.269531, 1.0)
#Tan (0.996094, 0.695312, 0.511719, 1.0)
#Coral (0.832031, 0.5, 0.296875, 1.0)
#Orange (0.992188, 0.480469, 0.167969, 1.0)
#Yellow (0.996094, 0.898438, 0.320312, 1.0)
#Cream (0.996094, 0.957031, 0.597656, 1.0)
#Citrine (0.855469, 0.933594, 0.492188, 1.0)
#Lime Green (0.550781, 0.824219, 0.324219, 1.0)
#Sea Green (0.242188, 0.742188, 0.515625, 1.0)
#Green (0.304688, 0.96875, 0.402344, 1.0)
#Light Blue (0.433594, 0.90625, 0.835938, 1.0)
#Aqua (0.347656, 0.820312, 0.953125, 1.0)
#Blue (0.191406, 0.5625, 0.773438, 1.0)
#Periwinkle (0.558594, 0.589844, 0.875, 1.0)
#Royal Blue (0.285156, 0.328125, 0.726562, 1.0)
#Slate Blue (0.460938, 0.378906, 0.824219, 1.0)
#Purple (0.546875, 0.28125, 0.75, 1.0)
#Lavender (0.726562, 0.472656, 0.859375, 1.0)
#Pink (0.898438, 0.617188, 0.90625, 1.0)
#Gray (0.7, 0.7, 0.8, 1.0)
#Black (0.3, 0.3, 0.35, 1.0)

#Toon Colors
arms.setColor(0.285156, 0.328125, 0.726562, 1.0)
legs.setColor(0.285156, 0.328125, 0.726562, 1.)
neck.setColor(0.285156, 0.328125, 0.726562, 1.0)
backhead.setColor(0.285156, 0.328125, 0.726562, 1.0)
head.setColor(0.285156, 0.328125, 0.726562, 1.0)
#feet.setColor(0.285156, 0.328125, 0.726562, 1.0) #remove this if you want shoes



#Find Joint for Hats
defhead = dog.find('**/def_head')
#Load Hat Model
hat = loader.loadModel ('phase_4/models/accessories/tt_m_chr_avt_acc_hat_sombreroHat.bam')
#Reparent to Joint
hat.reparentTo(defhead)
#Load Texture
hattxt = loader.loadTexture ("phase_4/maps/tt_t_chr_avt_acc_hat_sombreroHat.jpg")
txt = hat.setTexture(hattxt, 1)
#Positions
hat.setPosHprScale(0.00, -0.02, 0.50, 180.00, 337.38, 0.00, 0.29, 0.29, 0.29)

#Masks
nasalconfidant = dog.find('**/def_head')
mask = loader.loadModel("phase_4/models/accessories/tt_m_chr_avt_acc_msk_3dGlasses.bam")
mask.reparentTo(nasalconfidant)
mask.setPosHprScale(0.00, 0.14, 0.25, 180.00, 347.91, 0.00, 0.29, 0.29, 0.29)
masktxt = loader.loadTexture ("phase_4/maps/tt_t_chr_avt_acc_msk_3dGlasses.jpg")
txt = mask.setTexture(masktxt, 1)
#Backpack
back = dog.find('**/def_joint_attachFlower')
backpack = loader.loadModel("phase_4/models/accessories/tt_m_chr_avt_acc_pac_sharkFin.bam")
backpack.reparentTo(back)
backpack.setPosHprScale(0.23, -0.98, 0.05, 180.00, 0.00, 357.27, 0.33, 0.33, 0.33)
backpacktxt = loader.loadTexture ("phase_4/maps/tt_t_chr_avt_acc_pac_sharkFin.jpg")
txt = backpack.setTexture(backpacktxt, 1)

#dog.setX(0)
#dog.setY(0)
#dog.setZ(-2.75)
#dog.setH(180)

dog.place()

#dog.setPlayRate(0.001, 'run')
#dog.pose('run', 44) #good for neutral
#dog.pose('run', 8) #good for run
#dog.pose('run', 52) #good for periscope

#dog.pose('run', 21) #good for push
#dog.pose('run', 75) #good for victory-dance

print dog.getNumFrames('run')

#Camera
base.cam.setZ(2.75)
#base.cam.setH(180)

#You might just want to enter these coordinates manually to look at the neutral face.
#base.cam.setPosHprScale(0.91, 6, -4, 150.71, 0, 0, 1, 1, 1)

#More manual coordinates. This time to look at running feet.
#base.cam.setPosHprScale(0.75, 7.20, -0.75, 90.00, 0, 0, 1, 1, 1)

base.disableMouse()
base.useDrive()
base.useTrackball()

shadow = loader.loadModel("phase_3/models/props/drop_shadow.bam")
shadow.reparentTo(render)
shadow.reparentTo(dog.find('**/joint_shadow'))

shadow.setSx(0.5)
shadow.setSy(0.5)

run()

#phase_4/models/accessories/tt_m_chr_avt_acc_hat_sombreroHat.bam
#phase_4/models/accessories/tt_m_chr_avt_acc_pac_sharkFin.bam
#phase_4/models/accessories/tt_m_chr_avt_acc_msk_3dGlasses.bam

Output

Notes

  • When Toontown Online was updated to support accessories, Toon animations lost a lot of their squash-and-stretch functionality. Frame 8 of 16 of the run animation in particular has made the Toon's left foot look really messed up and warped.
  • In 2018, Toontown Rewritten released new versions of the Toon/Cog models and animations as part of Toontown Rerigged. As a side effect, Toons' drop shadows no longer shift with their weight when they walk and/or run. For running, something about the new "phase_3/models/char/tt_a_chr_dgm_shorts_legs_run.bam" animation doesn't make the shadow move. Applying an older animation on the newer leg model will actually make the shadow move like normal. Gameplay-related videos (eg. The Options Update) still have the shadow move when running, but more cut-scene-style videos (eg. Silly Meter Test #1) don't. Your mileage may vary.
Community content is available under CC-BY-SA unless otherwise noted.