Module pyxyz.object3d
3d Object class
Expand source code
"""3d Object class"""
import numpy as np
from quaternion import quaternion, as_rotation_matrix
from pyxyz.vector3 import Vector3
class Object3d:
"""3d object class.
This is the base class of all objects added to the scene graph.
"""
def __init__(self, name):
"""
Arguments:
name {str} -- Name of the object
"""
self.name = name
""" {str} Name of the object"""
self.position = Vector3()
""" {Vector3} Local position of the object (relative to parent)"""
self.rotation = quaternion(1, 0, 0, 0)
""" {quaternion} Local rotation of the object {relative to parent)"""
self.scale = Vector3(1, 1, 1)
""" {Vector3} Local scale of the object (relative to parent)"""
self.mesh = None
""" {Mesh} Mesh to be rendered in this object"""
self.material = None
""" {Material} Material to be used rendering this object"""
self.children = []
""" {List[Object3d]} Children objects of this object"""
def get_matrix(self):
"""
Retrieves the local transformation matrix of this object
Returns:
{np.array} -- Local transformation matrix
"""
return Object3d.get_prs_matrix(self.position, self.rotation, self.scale)
def render(self, screen, clip_matrix):
"""
Renders this object with the given clip_matrix.
Arguments:
screen {pygame.Surface} -- Pygame surface in which this object will be rendered
clip_matrix {np.array} -- Parent transformation matrix (including view and projection
matrix)
"""
# Retrieve the local transformation matrix
world_matrix = self.get_matrix()
# Multiply the local transformation with the clip matrix (transformation compositing)
mesh_matrix = world_matrix @ clip_matrix
# If there's a mesh and a material
if ((self.material is not None) and (self.mesh is not None)):
self.mesh.render(screen, mesh_matrix, self.material)
# Traverse the children of this object, rendering them
for child in self.children:
child.render(screen, mesh_matrix)
def add_child(self, obj):
"""
Adds a child object to the hierarchy of this one
Arguments:
obj {Object3d} -- Object to add to the hierarchy
"""
self.children.append(obj)
def remove_child(self, obj):
"""
Removes a child object from the hierarchy of this one. If the object isn't a child of
this one, nothing happens
Arguments:
obj {Object3d} -- Object to remove from the hierarchy
"""
if obj in self.children:
self.children.remove(obj)
def get_position(self):
"""
Retrieves the local position of this object. You can use self.position instead, this
method actually computes the transfomation matrix and multiplies the 4d vector (0,0,0,1)
by it. Results should be very similar.
Returns:
{Vector3} - Local position of the object
"""
return Vector3.from_np(Vector3(0, 0, 0).to_np4(1) @ self.get_matrix())
def forward(self):
"""
Retrieves the local forward vector of this object. The forward vector is defined as
being the z-positive vector multiplied with the local transformation matrix
Returns:
{Vector3} - Local forward vector of the object
"""
return Vector3.from_np(Vector3(0, 0, 1).to_np4(0) @ self.get_matrix())
def up(self):
"""
Retrieves the local up vector of this object. The up vector is defined as being
the y-positive vector multiplied with the local transformation matrix
Returns:
{Vector3} - Local up vector of the object
"""
return Vector3.from_np(Vector3(0, 1, 0).to_np4(0) @ self.get_matrix())
def right(self):
"""
Retrieves the local right vector of this object. The right vector is defined as being
the x-positive vector multiplied with the local transformation matrix
Returns:
{Vector3} - Local right vector of the object
"""
return Vector3.from_np(Vector3(1, 0, 0).to_np4(0) @ self.get_matrix())
@staticmethod
def get_prs_matrix(position, rotation, scale):
"""
Creates a PRS matrix from the given position, rotation and scale
Arguments:
position {Vector3} - Position
rotation {quaternion} - Rotation
scale {Vector3} - Scale
Returns:
{np.array} - PRS matrix
"""
trans = np.identity(4)
trans[3][0] = position.x
trans[3][1] = position.y
trans[3][2] = position.z
qrot = as_rotation_matrix(rotation)
rotation_matrix = np.identity(4)
rotation_matrix[0][0] = qrot[0][0]
rotation_matrix[0][1] = qrot[0][1]
rotation_matrix[0][2] = qrot[0][2]
rotation_matrix[1][0] = qrot[1][0]
rotation_matrix[1][1] = qrot[1][1]
rotation_matrix[1][2] = qrot[1][2]
rotation_matrix[2][0] = qrot[2][0]
rotation_matrix[2][1] = qrot[2][1]
rotation_matrix[2][2] = qrot[2][2]
rotation_matrix[3][3] = 1
scale_matrix = np.identity(4)
scale_matrix[0][0] = scale.x
scale_matrix[1][1] = scale.y
scale_matrix[2][2] = scale.z
return scale_matrix @ rotation_matrix @ trans
Classes
class Object3d (name)
-
3d object class. This is the base class of all objects added to the scene graph.
Arguments
name {str} – Name of the object
Expand source code
class Object3d: """3d object class. This is the base class of all objects added to the scene graph. """ def __init__(self, name): """ Arguments: name {str} -- Name of the object """ self.name = name """ {str} Name of the object""" self.position = Vector3() """ {Vector3} Local position of the object (relative to parent)""" self.rotation = quaternion(1, 0, 0, 0) """ {quaternion} Local rotation of the object {relative to parent)""" self.scale = Vector3(1, 1, 1) """ {Vector3} Local scale of the object (relative to parent)""" self.mesh = None """ {Mesh} Mesh to be rendered in this object""" self.material = None """ {Material} Material to be used rendering this object""" self.children = [] """ {List[Object3d]} Children objects of this object""" def get_matrix(self): """ Retrieves the local transformation matrix of this object Returns: {np.array} -- Local transformation matrix """ return Object3d.get_prs_matrix(self.position, self.rotation, self.scale) def render(self, screen, clip_matrix): """ Renders this object with the given clip_matrix. Arguments: screen {pygame.Surface} -- Pygame surface in which this object will be rendered clip_matrix {np.array} -- Parent transformation matrix (including view and projection matrix) """ # Retrieve the local transformation matrix world_matrix = self.get_matrix() # Multiply the local transformation with the clip matrix (transformation compositing) mesh_matrix = world_matrix @ clip_matrix # If there's a mesh and a material if ((self.material is not None) and (self.mesh is not None)): self.mesh.render(screen, mesh_matrix, self.material) # Traverse the children of this object, rendering them for child in self.children: child.render(screen, mesh_matrix) def add_child(self, obj): """ Adds a child object to the hierarchy of this one Arguments: obj {Object3d} -- Object to add to the hierarchy """ self.children.append(obj) def remove_child(self, obj): """ Removes a child object from the hierarchy of this one. If the object isn't a child of this one, nothing happens Arguments: obj {Object3d} -- Object to remove from the hierarchy """ if obj in self.children: self.children.remove(obj) def get_position(self): """ Retrieves the local position of this object. You can use self.position instead, this method actually computes the transfomation matrix and multiplies the 4d vector (0,0,0,1) by it. Results should be very similar. Returns: {Vector3} - Local position of the object """ return Vector3.from_np(Vector3(0, 0, 0).to_np4(1) @ self.get_matrix()) def forward(self): """ Retrieves the local forward vector of this object. The forward vector is defined as being the z-positive vector multiplied with the local transformation matrix Returns: {Vector3} - Local forward vector of the object """ return Vector3.from_np(Vector3(0, 0, 1).to_np4(0) @ self.get_matrix()) def up(self): """ Retrieves the local up vector of this object. The up vector is defined as being the y-positive vector multiplied with the local transformation matrix Returns: {Vector3} - Local up vector of the object """ return Vector3.from_np(Vector3(0, 1, 0).to_np4(0) @ self.get_matrix()) def right(self): """ Retrieves the local right vector of this object. The right vector is defined as being the x-positive vector multiplied with the local transformation matrix Returns: {Vector3} - Local right vector of the object """ return Vector3.from_np(Vector3(1, 0, 0).to_np4(0) @ self.get_matrix()) @staticmethod def get_prs_matrix(position, rotation, scale): """ Creates a PRS matrix from the given position, rotation and scale Arguments: position {Vector3} - Position rotation {quaternion} - Rotation scale {Vector3} - Scale Returns: {np.array} - PRS matrix """ trans = np.identity(4) trans[3][0] = position.x trans[3][1] = position.y trans[3][2] = position.z qrot = as_rotation_matrix(rotation) rotation_matrix = np.identity(4) rotation_matrix[0][0] = qrot[0][0] rotation_matrix[0][1] = qrot[0][1] rotation_matrix[0][2] = qrot[0][2] rotation_matrix[1][0] = qrot[1][0] rotation_matrix[1][1] = qrot[1][1] rotation_matrix[1][2] = qrot[1][2] rotation_matrix[2][0] = qrot[2][0] rotation_matrix[2][1] = qrot[2][1] rotation_matrix[2][2] = qrot[2][2] rotation_matrix[3][3] = 1 scale_matrix = np.identity(4) scale_matrix[0][0] = scale.x scale_matrix[1][1] = scale.y scale_matrix[2][2] = scale.z return scale_matrix @ rotation_matrix @ trans
Subclasses
Static methods
def get_prs_matrix(position, rotation, scale)
-
Creates a PRS matrix from the given position, rotation and scale
Arguments
position {Vector3} - Position
rotation {quaternion} - Rotation
scale {Vector3} - Scale
Returns
{np.array} - PRS matrix
Expand source code
@staticmethod def get_prs_matrix(position, rotation, scale): """ Creates a PRS matrix from the given position, rotation and scale Arguments: position {Vector3} - Position rotation {quaternion} - Rotation scale {Vector3} - Scale Returns: {np.array} - PRS matrix """ trans = np.identity(4) trans[3][0] = position.x trans[3][1] = position.y trans[3][2] = position.z qrot = as_rotation_matrix(rotation) rotation_matrix = np.identity(4) rotation_matrix[0][0] = qrot[0][0] rotation_matrix[0][1] = qrot[0][1] rotation_matrix[0][2] = qrot[0][2] rotation_matrix[1][0] = qrot[1][0] rotation_matrix[1][1] = qrot[1][1] rotation_matrix[1][2] = qrot[1][2] rotation_matrix[2][0] = qrot[2][0] rotation_matrix[2][1] = qrot[2][1] rotation_matrix[2][2] = qrot[2][2] rotation_matrix[3][3] = 1 scale_matrix = np.identity(4) scale_matrix[0][0] = scale.x scale_matrix[1][1] = scale.y scale_matrix[2][2] = scale.z return scale_matrix @ rotation_matrix @ trans
Instance variables
var children
-
{List[Object3d]} Children objects of this object
var material
-
{Material} Material to be used rendering this object
var mesh
-
{Mesh} Mesh to be rendered in this object
var name
-
{str} Name of the object
var position
-
{Vector3} Local position of the object (relative to parent)
var rotation
-
{quaternion} Local rotation of the object {relative to parent)
var scale
-
{Vector3} Local scale of the object (relative to parent)
Methods
def add_child(self, obj)
-
Adds a child object to the hierarchy of this one
Arguments
obj {Object3d} – Object to add to the hierarchy
Expand source code
def add_child(self, obj): """ Adds a child object to the hierarchy of this one Arguments: obj {Object3d} -- Object to add to the hierarchy """ self.children.append(obj)
def forward(self)
-
Retrieves the local forward vector of this object. The forward vector is defined as being the z-positive vector multiplied with the local transformation matrix
Returns
{Vector3} - Local forward vector of the object
Expand source code
def forward(self): """ Retrieves the local forward vector of this object. The forward vector is defined as being the z-positive vector multiplied with the local transformation matrix Returns: {Vector3} - Local forward vector of the object """ return Vector3.from_np(Vector3(0, 0, 1).to_np4(0) @ self.get_matrix())
def get_matrix(self)
-
Retrieves the local transformation matrix of this object
Returns
{np.array} – Local transformation matrix
Expand source code
def get_matrix(self): """ Retrieves the local transformation matrix of this object Returns: {np.array} -- Local transformation matrix """ return Object3d.get_prs_matrix(self.position, self.rotation, self.scale)
def get_position(self)
-
Retrieves the local position of this object. You can use self.position instead, this method actually computes the transfomation matrix and multiplies the 4d vector (0,0,0,1) by it. Results should be very similar.
Returns
{Vector3} - Local position of the object
Expand source code
def get_position(self): """ Retrieves the local position of this object. You can use self.position instead, this method actually computes the transfomation matrix and multiplies the 4d vector (0,0,0,1) by it. Results should be very similar. Returns: {Vector3} - Local position of the object """ return Vector3.from_np(Vector3(0, 0, 0).to_np4(1) @ self.get_matrix())
def remove_child(self, obj)
-
Removes a child object from the hierarchy of this one. If the object isn't a child of this one, nothing happens
Arguments
obj {Object3d} – Object to remove from the hierarchy
Expand source code
def remove_child(self, obj): """ Removes a child object from the hierarchy of this one. If the object isn't a child of this one, nothing happens Arguments: obj {Object3d} -- Object to remove from the hierarchy """ if obj in self.children: self.children.remove(obj)
def render(self, screen, clip_matrix)
-
Renders this object with the given clip_matrix.
Arguments
screen {pygame.Surface} – Pygame surface in which this object will be rendered
clip_matrix {np.array} – Parent transformation matrix (including view and projection matrix)
Expand source code
def render(self, screen, clip_matrix): """ Renders this object with the given clip_matrix. Arguments: screen {pygame.Surface} -- Pygame surface in which this object will be rendered clip_matrix {np.array} -- Parent transformation matrix (including view and projection matrix) """ # Retrieve the local transformation matrix world_matrix = self.get_matrix() # Multiply the local transformation with the clip matrix (transformation compositing) mesh_matrix = world_matrix @ clip_matrix # If there's a mesh and a material if ((self.material is not None) and (self.mesh is not None)): self.mesh.render(screen, mesh_matrix, self.material) # Traverse the children of this object, rendering them for child in self.children: child.render(screen, mesh_matrix)
def right(self)
-
Retrieves the local right vector of this object. The right vector is defined as being the x-positive vector multiplied with the local transformation matrix
Returns
{Vector3} - Local right vector of the object
Expand source code
def right(self): """ Retrieves the local right vector of this object. The right vector is defined as being the x-positive vector multiplied with the local transformation matrix Returns: {Vector3} - Local right vector of the object """ return Vector3.from_np(Vector3(1, 0, 0).to_np4(0) @ self.get_matrix())
def up(self)
-
Retrieves the local up vector of this object. The up vector is defined as being the y-positive vector multiplied with the local transformation matrix
Returns
{Vector3} - Local up vector of the object
Expand source code
def up(self): """ Retrieves the local up vector of this object. The up vector is defined as being the y-positive vector multiplied with the local transformation matrix Returns: {Vector3} - Local up vector of the object """ return Vector3.from_np(Vector3(0, 1, 0).to_np4(0) @ self.get_matrix())