or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

animation.mdapplication-framework.mdasset-loading.mdaudio.mdindex.mdinput.mdmathematics.mdscene-graph.mdtask-event.mduser-interface.md

animation.mddocs/

0

# Animation and Characters

1

2

Panda3D provides comprehensive animation capabilities including character animation, procedural animation, and smooth interpolation systems for creating dynamic 3D content.

3

4

## Capabilities

5

6

### Actor - Animated Character System

7

8

The Actor class handles animated 3D characters with skeletal animation, multiple animation sets, and advanced playback control.

9

10

```python { .api }

11

class Actor:

12

def __init__(self,

13

model: str = None,

14

anims: dict = None,

15

copy: bool = True,

16

flattenable: bool = True,

17

setFinal: bool = False) -> None:

18

"""

19

Create animated character.

20

21

Args:

22

model: Path to character model file

23

anims: Dictionary mapping animation names to file paths

24

copy: Whether to copy geometry (True) or instance it (False)

25

flattenable: Whether model can be flattened for optimization

26

setFinal: Whether to finalize model structure

27

"""

28

29

def loadModel(self, modelPath: str) -> None:

30

"""Load character model from file."""

31

32

def loadAnims(self, anims: dict) -> None:

33

"""Load animation files. Dict maps names to file paths."""

34

35

def bindAnim(self, animName: str, animPath: str, partName: str = None) -> None:

36

"""Bind single animation to character or part."""

37

38

def unloadAnims(self, animNames: list = None, partNames: list = None) -> None:

39

"""Unload specified animations."""

40

41

def getAnimNames(self, partName: str = None) -> list:

42

"""Get list of loaded animation names."""

43

44

def hasAnim(self, animName: str) -> bool:

45

"""Check if animation is loaded."""

46

```

47

48

### Animation Playback Control

49

50

Control animation playback with various modes, blending, and timing options.

51

52

```python { .api }

53

class Actor:

54

def play(self, animName: str, partName: str = None, fromFrame: int = None, toFrame: int = None) -> None:

55

"""Play animation once from start to end."""

56

57

def loop(self, animName: str, partName: str = None, fromFrame: int = None, toFrame: int = None) -> None:

58

"""Loop animation continuously."""

59

60

def pingpong(self, animName: str, partName: str = None, fromFrame: int = None, toFrame: int = None) -> None:

61

"""Play animation back and forth."""

62

63

def stop(self, partName: str = None) -> None:

64

"""Stop animation playback."""

65

66

def pause(self, partName: str = None) -> None:

67

"""Pause animation at current frame."""

68

69

def resume(self, partName: str = None) -> None:

70

"""Resume paused animation."""

71

72

def pose(self, animName: str, frame: int, partName: str = None) -> None:

73

"""Set character to specific animation frame."""

74

75

def isPlaying(self, animName: str = None, partName: str = None) -> bool:

76

"""Check if animation is currently playing."""

77

78

def getCurrentAnim(self, partName: str = None) -> str:

79

"""Get name of currently playing animation."""

80

81

def getCurrentFrame(self, partName: str = None) -> int:

82

"""Get current animation frame number."""

83

84

def getNumFrames(self, animName: str = None, partName: str = None) -> int:

85

"""Get total frames in animation."""

86

87

def getDuration(self, animName: str = None, partName: str = None) -> float:

88

"""Get animation duration in seconds."""

89

90

def getFrameRate(self, animName: str = None, partName: str = None) -> float:

91

"""Get animation frame rate."""

92

93

def setPlayRate(self, rate: float, animName: str = None, partName: str = None) -> None:

94

"""Set animation playback speed multiplier."""

95

96

def getPlayRate(self, animName: str = None, partName: str = None) -> float:

97

"""Get current playback rate."""

98

```

99

100

### Animation Blending and Transitions

101

102

Advanced animation features for smooth transitions and blending between animations.

103

104

```python { .api }

105

class Actor:

106

def enableBlend(self, blendType: int = 0, partName: str = None) -> None:

107

"""Enable animation blending."""

108

109

def disableBlend(self, partName: str = None) -> None:

110

"""Disable animation blending."""

111

112

def setBlend(self,

113

animBlend: bool = True,

114

frameBlend: bool = True,

115

blendType: int = 0,

116

partName: str = None) -> None:

117

"""Configure blending options."""

118

119

def setControlEffect(self, animName: str, effect: float, partName: str = None) -> None:

120

"""Set animation influence/weight (0.0-1.0)."""

121

122

def getControlEffect(self, animName: str, partName: str = None) -> float:

123

"""Get animation influence/weight."""

124

```

125

126

### Multi-Part Characters

127

128

Support for characters with multiple independently animated parts.

129

130

```python { .api }

131

class Actor:

132

def makeSubpart(self, partName: str, includeJoints: list, excludeJoints: list = []) -> None:

133

"""Create animation subpart from specified joints."""

134

135

def getPartNames(self) -> list:

136

"""Get list of all part names."""

137

138

def removePart(self, partName: str) -> None:

139

"""Remove animation part."""

140

141

def hidePart(self, partName: str) -> None:

142

"""Hide part geometry."""

143

144

def showPart(self, partName: str) -> None:

145

"""Show part geometry."""

146

147

def showAllParts(self) -> None:

148

"""Show all parts."""

149

```

150

151

### Procedural Animation with Intervals

152

153

The interval system provides procedural animation through interpolation of object properties over time.

154

155

```python { .api }

156

class LerpPosInterval:

157

def __init__(self, nodePath: NodePath,

158

duration: float,

159

pos: Vec3,

160

startPos: Vec3 = None,

161

blendType: str = 'noBlend') -> None:

162

"""Animate object position over time."""

163

164

class LerpHprInterval:

165

def __init__(self, nodePath: NodePath,

166

duration: float,

167

hpr: Vec3,

168

startHpr: Vec3 = None,

169

blendType: str = 'noBlend') -> None:

170

"""Animate object rotation over time."""

171

172

class LerpScaleInterval:

173

def __init__(self, nodePath: NodePath,

174

duration: float,

175

scale: Vec3,

176

startScale: Vec3 = None,

177

blendType: str = 'noBlend') -> None:

178

"""Animate object scale over time."""

179

180

class LerpColorInterval:

181

def __init__(self, nodePath: NodePath,

182

duration: float,

183

color: Vec4,

184

startColor: Vec4 = None,

185

blendType: str = 'noBlend') -> None:

186

"""Animate object color over time."""

187

188

class LerpColorScaleInterval:

189

def __init__(self, nodePath: NodePath,

190

duration: float,

191

colorScale: Vec4,

192

startColorScale: Vec4 = None,

193

blendType: str = 'noBlend') -> None:

194

"""Animate color scale over time."""

195

```

196

197

### Composite Animation Sequences

198

199

Create complex animations by combining multiple intervals in sequences and parallel groups.

200

201

```python { .api }

202

class Sequence:

203

def __init__(self, *intervals) -> None:

204

"""Create sequence of intervals that play one after another."""

205

206

def start(self) -> None:

207

"""Start the sequence."""

208

209

def finish(self) -> None:

210

"""Jump to end of sequence."""

211

212

def pause(self) -> None:

213

"""Pause sequence playback."""

214

215

def resume(self) -> None:

216

"""Resume paused sequence."""

217

218

def loop(self) -> None:

219

"""Loop sequence continuously."""

220

221

def isPlaying(self) -> bool:

222

"""Check if sequence is playing."""

223

224

def getDuration(self) -> float:

225

"""Get total sequence duration."""

226

227

class Parallel:

228

def __init__(self, *intervals) -> None:

229

"""Create group of intervals that play simultaneously."""

230

231

def start(self) -> None: ...

232

def finish(self) -> None: ...

233

def pause(self) -> None: ...

234

def resume(self) -> None: ...

235

def loop(self) -> None: ...

236

def isPlaying(self) -> bool: ...

237

def getDuration(self) -> float: ...

238

239

def Wait(duration: float) -> WaitInterval:

240

"""Create pause/delay interval."""

241

242

def Func(function: callable, *args) -> FunctionInterval:

243

"""Create interval that calls function."""

244

```

245

246

### Animation Easing and Blending

247

248

Control animation curves and transitions for more natural motion.

249

250

```python { .api }

251

# Easing functions for smooth animation curves

252

def easeIn(t: float) -> float:

253

"""Ease-in curve (slow start)."""

254

255

def easeOut(t: float) -> float:

256

"""Ease-out curve (slow end)."""

257

258

def easeInOut(t: float) -> float:

259

"""Ease-in-out curve (slow start and end)."""

260

261

# Blend types for intervals

262

BLEND_EASE_IN = "easeIn"

263

BLEND_EASE_OUT = "easeOut"

264

BLEND_EASE_IN_OUT = "easeInOut"

265

BLEND_NO_BLEND = "noBlend"

266

```

267

268

## Usage Examples

269

270

### Basic Character Animation

271

272

```python

273

from direct.showbase.ShowBase import ShowBase

274

from direct.actor.Actor import Actor

275

from panda3d.core import Vec3

276

277

class CharacterDemo(ShowBase):

278

def __init__(self):

279

ShowBase.__init__(self)

280

281

# Load animated character

282

self.character = Actor(

283

"models/characters/panda",

284

{

285

"walk": "models/characters/panda-walk",

286

"run": "models/characters/panda-run",

287

"idle": "models/characters/panda-idle"

288

}

289

)

290

291

self.character.reparentTo(self.render)

292

self.character.setScale(0.5)

293

self.character.setPos(0, 10, 0)

294

295

# Start with idle animation

296

self.character.loop("idle")

297

298

# Setup input

299

self.accept("1", self.playIdle)

300

self.accept("2", self.playWalk)

301

self.accept("3", self.playRun)

302

303

def playIdle(self):

304

"""Switch to idle animation."""

305

self.character.loop("idle")

306

307

def playWalk(self):

308

"""Switch to walking animation."""

309

self.character.loop("walk")

310

311

def playRun(self):

312

"""Switch to running animation."""

313

self.character.loop("run")

314

315

app = CharacterDemo()

316

app.run()

317

```

318

319

### Procedural Animation with Intervals

320

321

```python

322

from direct.showbase.ShowBase import ShowBase

323

from direct.interval.IntervalGlobal import *

324

from panda3d.core import Vec3

325

326

class AnimationDemo(ShowBase):

327

def __init__(self):

328

ShowBase.__init__(self)

329

330

# Create object to animate

331

self.cube = self.loader.loadModel("models/cube")

332

self.cube.reparentTo(self.render)

333

self.cube.setPos(-5, 10, 0)

334

335

# Create complex animation sequence

336

self.createAnimation()

337

338

# Start animation

339

self.accept("space", self.startAnimation)

340

341

def createAnimation(self):

342

"""Create complex animation sequence."""

343

# Move right while growing

344

move_right = LerpPosInterval(

345

self.cube, 2.0, Vec3(5, 10, 0), blendType='easeInOut'

346

)

347

grow = LerpScaleInterval(

348

self.cube, 2.0, Vec3(2, 2, 2), blendType='easeInOut'

349

)

350

351

# Parallel movement and scaling

352

phase1 = Parallel(move_right, grow)

353

354

# Rotate and change color

355

rotate = LerpHprInterval(

356

self.cube, 1.5, Vec3(360, 0, 0)

357

)

358

color_change = LerpColorInterval(

359

self.cube, 1.5, (1, 0, 0, 1) # Red

360

)

361

362

phase2 = Parallel(rotate, color_change)

363

364

# Move up with pause

365

pause = Wait(0.5)

366

move_up = LerpPosInterval(

367

self.cube, 1.0, Vec3(5, 10, 3), blendType='easeOut'

368

)

369

370

# Final callback

371

finish_func = Func(self.onAnimationComplete)

372

373

# Combine into sequence

374

self.animation = Sequence(

375

phase1,

376

phase2,

377

pause,

378

move_up,

379

finish_func

380

)

381

382

def startAnimation(self):

383

"""Start the animation sequence."""

384

# Reset object state

385

self.cube.setPos(-5, 10, 0)

386

self.cube.setScale(1, 1, 1)

387

self.cube.setHpr(0, 0, 0)

388

self.cube.clearColor()

389

390

# Start animation

391

self.animation.start()

392

393

def onAnimationComplete(self):

394

"""Called when animation finishes."""

395

print("Animation completed!")

396

397

# Loop the animation

398

self.startAnimation()

399

400

app = AnimationDemo()

401

app.run()

402

```

403

404

### Multi-Part Character Animation

405

406

```python

407

from direct.showbase.ShowBase import ShowBase

408

from direct.actor.Actor import Actor

409

410

class MultiPartDemo(ShowBase):

411

def __init__(self):

412

ShowBase.__init__(self)

413

414

# Load character with multiple parts

415

self.character = Actor("models/characters/robot")

416

self.character.loadAnims({

417

"torso_idle": "models/anims/robot-torso-idle",

418

"torso_wave": "models/anims/robot-torso-wave",

419

"legs_walk": "models/anims/robot-legs-walk",

420

"legs_run": "models/anims/robot-legs-run"

421

})

422

423

self.character.reparentTo(self.render)

424

425

# Create animation parts

426

self.character.makeSubpart(

427

"torso",

428

["torso", "left_arm", "right_arm", "head"]

429

)

430

self.character.makeSubpart(

431

"legs",

432

["left_leg", "right_leg", "pelvis"]

433

)

434

435

# Start different animations on different parts

436

self.character.loop("torso_idle", partName="torso")

437

self.character.loop("legs_walk", partName="legs")

438

439

# Setup controls

440

self.accept("w", self.wave)

441

self.accept("r", self.run)

442

self.accept("s", self.stop)

443

444

def wave(self):

445

"""Play wave animation on torso."""

446

self.character.play("torso_wave", partName="torso")

447

448

# Return to idle after wave completes

449

duration = self.character.getDuration("torso_wave", "torso")

450

self.taskMgr.doMethodLater(

451

duration, self.returnToIdle, "return-idle"

452

)

453

454

def returnToIdle(self, task):

455

"""Return torso to idle animation."""

456

self.character.loop("torso_idle", partName="torso")

457

return task.done

458

459

def run(self):

460

"""Switch legs to running."""

461

self.character.loop("legs_run", partName="legs")

462

463

def stop(self):

464

"""Switch legs to walking."""

465

self.character.loop("legs_walk", partName="legs")

466

467

app = MultiPartDemo()

468

app.run()

469

```

470

471

## Types

472

473

```python { .api }

474

class AnimControl:

475

"""Animation control object for fine-tuned animation management."""

476

def play(self) -> None: ...

477

def stop(self) -> None: ...

478

def pose(self, frame: int) -> None: ...

479

480

class PartBundle:

481

"""Animation part bundle for multi-part characters."""

482

def getName(self) -> str: ...

483

def update(self) -> None: ...

484

485

# Animation blend types

486

BT_NO_BLEND = 0 # No blending

487

BT_NORMAL_BLEND = 1 # Normal animation blending

488

BT_ADDITIVE_BLEND = 2 # Additive blending

489

490

# Interval blend type constants

491

from direct.interval.IntervalGlobal import *

492

# Available blend types: 'noBlend', 'easeIn', 'easeOut', 'easeInOut'

493

```