Panda3D is a framework for 3D rendering and game development for Python and C++ programs.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Panda3D provides a comprehensive 3D mathematics library with vectors, matrices, quaternions, and geometric operations essential for 3D graphics, physics, and game development.
Vector classes for representing positions, directions, and other 3D quantities with full mathematical operations.
class Vec3:
def __init__(self, x: float = 0.0, y: float = 0.0, z: float = 0.0) -> None:
"""Create 3D vector with x, y, z components."""
def __init__(self, other: Vec3) -> None:
"""Copy constructor."""
# Component access
def getX(self) -> float:
"""Get X component."""
def getY(self) -> float:
"""Get Y component."""
def getZ(self) -> float:
"""Get Z component."""
def setX(self, x: float) -> None:
"""Set X component."""
def setY(self, y: float) -> None:
"""Set Y component."""
def setZ(self, z: float) -> None:
"""Set Z component."""
def set(self, x: float, y: float, z: float) -> None:
"""Set all components."""
# Vector operations
def length(self) -> float:
"""Get vector magnitude/length."""
def lengthSquared(self) -> float:
"""Get squared length (more efficient than length)."""
def normalize(self) -> None:
"""Normalize vector in place."""
def normalized(self) -> Vec3:
"""Return normalized copy of vector."""
def dot(self, other: Vec3) -> float:
"""Dot product with another vector."""
def cross(self, other: Vec3) -> Vec3:
"""Cross product with another vector."""
def distance(self, other: Vec3) -> float:
"""Distance to another point."""
def distanceSquared(self, other: Vec3) -> float:
"""Squared distance to another point."""
# Arithmetic operators (support + - * / with vectors and scalars)
def __add__(self, other: Vec3) -> Vec3: ...
def __sub__(self, other: Vec3) -> Vec3: ...
def __mul__(self, scalar: float) -> Vec3: ...
def __truediv__(self, scalar: float) -> Vec3: ...
def __neg__(self) -> Vec3: ...
# Comparison
def __eq__(self, other: Vec3) -> bool: ...
def __ne__(self, other: Vec3) -> bool: ...
# String representation
def __str__(self) -> str: ...
def __repr__(self) -> str: ...
# Type aliases for different precisions
Vec3F = LVector3f # Single precision (default)
Vec3D = LVector3d # Double precisionPoint classes for representing positions in 3D space, with similar interface to vectors but semantic differences.
class Point3:
def __init__(self, x: float = 0.0, y: float = 0.0, z: float = 0.0) -> None:
"""Create 3D point."""
def getX(self) -> float: ...
def getY(self) -> float: ...
def getZ(self) -> float: ...
def setX(self, x: float) -> None: ...
def setY(self, y: float) -> None: ...
def setZ(self, z: float) -> None: ...
def distance(self, other: Point3) -> float:
"""Distance to another point."""
def distanceSquared(self, other: Point3) -> float:
"""Squared distance to another point."""
# Arithmetic operations with vectors and points
def __add__(self, vector: Vec3) -> Point3: ...
def __sub__(self, other: Point3) -> Vec3: ... # Point - Point = Vector
def __sub__(self, vector: Vec3) -> Point3: ... # Point - Vector = Point
Point3F = LPoint3f # Single precision (default)
Point3D = LPoint3d # Double precisionExtended vectors for homogeneous coordinates and advanced mathematical operations.
class Vec4:
def __init__(self, x: float = 0.0, y: float = 0.0, z: float = 0.0, w: float = 0.0) -> None:
"""Create 4D vector."""
def getX(self) -> float: ...
def getY(self) -> float: ...
def getZ(self) -> float: ...
def getW(self) -> float: ...
def getXyz(self) -> Vec3:
"""Get XYZ components as Vec3."""
def length(self) -> float: ...
def normalize(self) -> None: ...
def normalized(self) -> Vec4: ...
def dot(self, other: Vec4) -> float: ...
Vec4F = LVector4f # Single precision
Vec4D = LVector4d # Double precisionMatrix operations for 3D transformations including translation, rotation, scaling, and projection.
class LMatrix4:
def __init__(self) -> None:
"""Create identity matrix."""
def __init__(self, other: LMatrix4) -> None:
"""Copy constructor."""
# Matrix creation
@staticmethod
def identMat() -> LMatrix4:
"""Create identity matrix."""
@staticmethod
def zeros() -> LMatrix4:
"""Create zero matrix."""
@staticmethod
def translateMat(trans: Vec3) -> LMatrix4:
"""Create translation matrix."""
@staticmethod
def scaleMat(scale: Vec3) -> LMatrix4:
"""Create scale matrix."""
@staticmethod
def rotateMat(angle: float, axis: Vec3) -> LMatrix4:
"""Create rotation matrix around axis."""
@staticmethod
def rotateMatNormaxis(angle: float, axis: Vec3) -> LMatrix4:
"""Create rotation matrix around normalized axis."""
# Element access
def getCell(self, row: int, col: int) -> float:
"""Get matrix element at row, col."""
def setCell(self, row: int, col: int, value: float) -> None:
"""Set matrix element at row, col."""
def getRow(self, row: int) -> Vec4:
"""Get row as Vec4."""
def getCol(self, col: int) -> Vec4:
"""Get column as Vec4."""
def setRow(self, row: int, v: Vec4) -> None:
"""Set row from Vec4."""
def setCol(self, col: int, v: Vec4) -> None:
"""Set column from Vec4."""
# Matrix operations
def multiply(self, other: LMatrix4) -> LMatrix4:
"""Matrix multiplication."""
def __mul__(self, other: LMatrix4) -> LMatrix4:
"""Matrix multiplication operator."""
def __mul__(self, vector: Vec4) -> Vec4:
"""Transform Vec4 by matrix."""
def xform(self, point: Point3) -> Point3:
"""Transform point by matrix."""
def xformVec(self, vector: Vec3) -> Vec3:
"""Transform vector by matrix (no translation)."""
def xformPoint(self, point: Point3) -> Point3:
"""Transform point by matrix."""
def invertFrom(self, other: LMatrix4) -> bool:
"""Invert other matrix and store result."""
def invert(self) -> bool:
"""Invert this matrix in place."""
def invertInPlace(self) -> bool:
"""Invert this matrix in place."""
def transpose(self) -> None:
"""Transpose matrix in place."""
def transposed(self) -> LMatrix4:
"""Return transposed copy."""
def determinant(self) -> float:
"""Calculate matrix determinant."""
# Transformation composition
def compose(self, scale: Vec3, hpr: Vec3, trans: Vec3) -> None:
"""Compose transformation from scale, rotation (HPR), and translation."""
def composeMatrix(self, scale: Vec3, shear: Vec3, hpr: Vec3, trans: Vec3) -> None:
"""Compose transformation with shear."""
def decompose(self) -> Tuple[Vec3, Vec3, Vec3]:
"""Decompose into scale, HPR, and translation."""
# Utility
def isIdentity(self) -> bool:
"""Check if matrix is identity."""
def almostEqual(self, other: LMatrix4, threshold: float = 0.001) -> bool:
"""Check if matrices are approximately equal."""
Mat4 = LMatrix4f # Single precision alias (default)
Mat4D = LMatrix4d # Double precisionQuaternion class for smooth rotations and orientation interpolation.
class LQuaternion:
def __init__(self, w: float = 1.0, x: float = 0.0, y: float = 0.0, z: float = 0.0) -> None:
"""Create quaternion with w, x, y, z components."""
def __init__(self, other: LQuaternion) -> None:
"""Copy constructor."""
# Component access
def getW(self) -> float: ...
def getX(self) -> float: ...
def getY(self) -> float: ...
def getZ(self) -> float: ...
def setW(self, w: float) -> None: ...
def setX(self, x: float) -> None: ...
def setY(self, y: float) -> None: ...
def setZ(self, z: float) -> None: ...
def set(self, w: float, x: float, y: float, z: float) -> None:
"""Set all components."""
# Quaternion operations
def normalize(self) -> None:
"""Normalize quaternion in place."""
def normalized(self) -> LQuaternion:
"""Return normalized copy."""
def conjugate(self) -> LQuaternion:
"""Return conjugate quaternion."""
def invert(self) -> None:
"""Invert quaternion in place."""
def inverted(self) -> LQuaternion:
"""Return inverted quaternion."""
def multiply(self, other: LQuaternion) -> LQuaternion:
"""Quaternion multiplication."""
def __mul__(self, other: LQuaternion) -> LQuaternion: ...
# Rotation creation and conversion
@staticmethod
def pureRotation(axis: Vec3, angle: float) -> LQuaternion:
"""Create rotation quaternion from axis and angle."""
def setFromAxisAngle(self, angle: float, axis: Vec3) -> None:
"""Set from axis-angle representation."""
def getAxisAngle(self) -> Tuple[float, Vec3]:
"""Get axis-angle representation."""
def setHpr(self, hpr: Vec3) -> None:
"""Set from Heading-Pitch-Roll angles."""
def getHpr(self) -> Vec3:
"""Get as Heading-Pitch-Roll angles."""
def getMatrix(self) -> LMatrix4:
"""Convert to rotation matrix."""
# Interpolation
def slerp(self, other: LQuaternion, t: float) -> LQuaternion:
"""Spherical linear interpolation between quaternions."""
def dot(self, other: LQuaternion) -> float:
"""Dot product with another quaternion."""
def isIdentity(self) -> bool:
"""Check if quaternion represents no rotation."""
def almostEqual(self, other: LQuaternion, threshold: float = 0.001) -> bool:
"""Check if quaternions are approximately equal."""
Quat = LQuaternionf # Single precision alias (default)
QuatD = LQuaterniond # Double precisionAdditional mathematical utilities for common 3D operations.
def deg2Rad(degrees: float) -> float:
"""Convert degrees to radians."""
def rad2Deg(radians: float) -> float:
"""Convert radians to degrees."""
def clamp(value: float, min_val: float, max_val: float) -> float:
"""Clamp value between min and max."""
def lerp(a: float, b: float, t: float) -> float:
"""Linear interpolation between a and b."""
def smoothstep(edge0: float, edge1: float, x: float) -> float:
"""Smooth interpolation function."""
# Vector utility functions
def cross(a: Vec3, b: Vec3) -> Vec3:
"""Cross product of two vectors."""
def dot(a: Vec3, b: Vec3) -> float:
"""Dot product of two vectors."""
def distance(a: Point3, b: Point3) -> float:
"""Distance between two points."""
def reflect(incident: Vec3, normal: Vec3) -> Vec3:
"""Reflect vector off surface with given normal."""from panda3d.core import Vec3, Point3
# Create vectors
a = Vec3(1, 2, 3)
b = Vec3(4, 5, 6)
# Basic operations
c = a + b # Vector addition: (5, 7, 9)
d = b - a # Vector subtraction: (3, 3, 3)
e = a * 2.0 # Scalar multiplication: (2, 4, 6)
# Vector properties
length = a.length() # Get magnitude
a.normalize() # Normalize in place
unit_a = a.normalized() # Get normalized copy
# Vector products
dot_product = a.dot(b) # Dot product (scalar)
cross_product = a.cross(b) # Cross product (vector)
# Distance calculations
p1 = Point3(0, 0, 0)
p2 = Point3(3, 4, 0)
dist = p1.distance(p2) # Distance: 5.0from panda3d.core import LMatrix4, Vec3, Point3
# Create transformation matrices
translate_mat = LMatrix4.translateMat(Vec3(5, 0, 0))
scale_mat = LMatrix4.scaleMat(Vec3(2, 2, 2))
rotate_mat = LMatrix4.rotateMat(45, Vec3(0, 0, 1)) # 45° around Z
# Combine transformations (order matters!)
transform = translate_mat * rotate_mat * scale_mat
# Apply transformation to points and vectors
point = Point3(1, 1, 0)
transformed_point = transform.xform(point)
vector = Vec3(1, 0, 0)
transformed_vector = transform.xformVec(vector)
# Matrix composition (more convenient)
final_mat = LMatrix4()
final_mat.compose(
Vec3(2, 2, 2), # Scale
Vec3(0, 0, 45), # HPR rotation
Vec3(5, 0, 0) # Translation
)from panda3d.core import LQuaternion, Vec3
import math
# Create rotation quaternions
q1 = LQuaternion()
q1.setFromAxisAngle(math.radians(90), Vec3(0, 0, 1)) # 90° around Z
q2 = LQuaternion()
q2.setHpr(Vec3(45, 0, 0)) # From HPR angles
# Quaternion multiplication (rotation composition)
combined = q1 * q2
# Interpolation between rotations
interpolated = q1.slerp(q2, 0.5) # Halfway between q1 and q2
# Convert to other representations
hpr = combined.getHpr() # Get as HPR angles
matrix = combined.getMatrix() # Get as rotation matrix
angle, axis = combined.getAxisAngle() # Get as axis-anglefrom direct.showbase.ShowBase import ShowBase
from panda3d.core import Vec3, Point3
from direct.task import Task
class MathDemo(ShowBase):
def __init__(self):
ShowBase.__init__(self)
# Create objects
self.player = self.loader.loadModel("models/player")
self.target = self.loader.loadModel("models/target")
self.player.reparentTo(self.render)
self.target.reparentTo(self.render)
# Position objects
self.player.setPos(0, 0, 0)
self.target.setPos(10, 5, 2)
# Start update task
self.taskMgr.add(self.updatePlayer, "update-player")
def updatePlayer(self, task):
"""Make player look at and move toward target."""
# Get positions as Point3
player_pos = self.player.getPos()
target_pos = self.target.getPos()
# Calculate direction vector
direction = target_pos - player_pos
distance = direction.length()
if distance > 0.1: # Not at target yet
# Normalize direction for unit vector
direction.normalize()
# Move toward target
speed = 5.0 # units per second
dt = globalClock.getDt()
new_pos = player_pos + direction * speed * dt
self.player.setPos(new_pos)
# Look at target
self.player.lookAt(target_pos)
return task.cont
app = MathDemo()
app.run()# Precision variants
LVector3f = Vec3F # Single precision 3D vector
LVector3d = Vec3D # Double precision 3D vector
LVector4f = Vec4F # Single precision 4D vector
LVector4d = Vec4D # Double precision 4D vector
LPoint3f = Point3F # Single precision 3D point
LPoint3d = Point3D # Double precision 3D point
LMatrix4f = Mat4 # Single precision 4x4 matrix
LMatrix4d = Mat4D # Double precision 4x4 matrix
LQuaternionf = Quat # Single precision quaternion
LQuaterniond = QuatD # Double precision quaternion
# Common type aliases used throughout Panda3D
Vec3 = LVector3f # Default 3D vector type
Point3 = LPoint3f # Default 3D point type
Mat4 = LMatrix4f # Default matrix type
Quat = LQuaternionf # Default quaternion typeInstall with Tessl CLI
npx tessl i tessl/pypi-panda3d