This repository has been archived on 2025-06-21. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
raylib-python-cffi/raylib/richlib/__init__.py
2019-06-07 03:51:03 +01:00

372 lines
9.2 KiB
Python
Executable file

""" Richlib, simple access to Raylib
"""
__version__ = '0.1'
from ..static import ffi, rl
#from ..dynamic import ffi, raylib as rl
from ..colors import *
import sys
data_dir = ""
from ..pyray import PyRay
pyray = PyRay()
camera = ffi.new("struct Camera3D *")
camera.position = (0.0, 100, 100)
camera.target = (0.0, 0.0, 0.0)
camera.up = (0, 1, 0)
camera.fovy = 45
camera.type = rl.CAMERA_PERSPECTIVE
mod = sys.modules['__main__']
class Vector(list):
@property
def x(self):
return self[0]
@x.setter
def x(self, value):
self[0] = value
@property
def y(self):
return self[1]
@y.setter
def y(self, value):
self[1] = value
@property
def z(self):
return self[2]
@z.setter
def z(self, value):
self[2] = value
@property
def w(self):
return self[3]
@w.setter
def w(self, value):
self[3] = value
class Color(list):
def __init__(self, s):
if isinstance(s, str):
super().__init__(globals()[s.upper()])
else:
super().__init__(s)
if len(self) == 3:
self.append(255)
@property
def r(self):
return self[0]
@r.setter
def r(self, value):
self[0] = value
@property
def g(self):
return self[1]
@g.setter
def g(self, value):
self[1] = value
@property
def b(self):
return self[2]
@b.setter
def b(self, value):
self[2] = value
@property
def a(self):
return self[3]
@a.setter
def a(self, value):
self[3] = value
def clear(color=BLACK):
rl.ClearBackground(Color(color))
class Shape:
@property
def color(self):
return self._color
@color.setter
def color(self, value):
self._color = Color(value)
@property
def pos(self):
return self._pos
@pos.setter
def pos(self, value):
self._pos = Vector(value)
@property
def wire_color(self):
return self._wire_color
@wire_color.setter
def wire_color(self, value):
self._wire_color = Color(value)
@property
def x(self):
return self.pos.x
@x.setter
def x(self, value):
self.pos.x = value
@property
def y(self):
return self.pos.y
@y.setter
def y(self, value):
self.pos.y = value
@property
def z(self):
return self.pos.z
@z.setter
def z(self, value):
self.pos.z = value
class Box(Shape):
def __init__(self, position, size, color=RED, wires=True, wire_color=DARKGRAY):
self.pos = position
self.size = size
self.color = color
self.wire_color = wire_color
self.wires = wires
# def __getattr__(self, item):
# return self.pos.item
#
# def __setattr__(self, key, value):
# self.pos.key = value
@property
def size(self):
return self._size
@size.setter
def size(self, value):
print("setting size ", value, type(value))
self._size = Vector(value)
def get_bounding_box(self):
return (
(
self.pos.x - self.size.x / 2,
self.pos.y - self.size.y / 2,
self.pos.z - self.size.z / 2,
),
(
self.pos.x + self.size.x / 2,
self.pos.y + self.size.y / 2,
self.pos.z + self.size.z / 2,
)
)
def draw(self):
#print("draw color ",self.color)
rl.DrawCubeV(self.pos, self.size, self.color)
if self.wires:
rl.DrawCubeWiresV(
self.pos, self.size, self.wire_color
)
def check_collision(self, other):
if isinstance(other, Sphere):
r = rl.CheckCollisionBoxSphere(
self.get_bounding_box(), other.pos, other.radius
)
return r
elif isinstance(other, Box):
return rl.CheckCollisionBoxes(self.get_bounding_box(), other.get_bounding_box())
elif isinstance(other, Actor):
return self.check_collision(other.collision_sphere)
class Sphere(Shape):
def __init__(self, position, radius, color=RED, wires=True, wire_color=DARKGRAY):
self.pos = position
self.radius = radius
self.color = color
self.wire_color = wire_color
self.wires = wires
def draw(self):
rl.DrawSphere(self.pos, self.radius, self.color)
if self.wires:
rl.DrawSphereWires(self.pos, self.radius, 32, 32, self.wire_color)
def check_collision(self, other):
if isinstance(other, Sphere):
return rl.CheckCollisionSpheres(
self.pos, self.radius, other.pos, other.radius
)
elif isinstance(other, Box):
return rl.CheckCollisionBoxSphere(
other.get_bounding_box(), self.pos, self.radius
)
elif isinstance(other, Actor):
return self.check_collision(other.collision_sphere)
class Actor(Shape):
def __init__(self, model_file, position=Vector([0, 0, 0]), collision_radius=1, texture_file="",
rotation_axis=Vector([0, 1, 0]), rotation_angle=0, scale=Vector([1, 1, 1]), color=WHITE, wires=False,
wire_color=DARKGRAY):
#super().__init__(position, collision_radius, color, wires, wire_color)
self.pos = position
self.color = color
self.wire_color = wire_color
self.wires = wires
self.model_file = model_file
if texture_file == "":
texture_file = model_file + "_diffuse"
self.texture_file = texture_file
self.scale = scale
self.rotation_axis = rotation_axis
self.rotation_angle = rotation_angle
self.collision_radius = collision_radius
self.collision_sphere = Sphere(position, collision_radius, RED)
self.loaded = False
def load_data(self):
self.loaded = True
print("*** DATA_DIR=", data_dir)
self.model = rl.LoadModel((data_dir + self.model_file + '.obj').encode('utf-8'))
texture = rl.LoadTexture((data_dir + self.texture_file + '.png').encode('utf-8'))
self.model.materials[0].maps[rl.MAP_DIFFUSE].texture = texture
def calc_bounding_box(self):
bb = rl.MeshBoundingBox(self.model.meshes[0])
bb.min.x *= self.scale.x
bb.min.y *= self.scale.y
bb.min.z *= self.scale.z
bb.max.x *= self.scale.x
bb.max.y *= self.scale.y
bb.max.z *= self.scale.z
bb.min.x += self.pos.x
bb.min.y += self.pos.y
bb.min.z += self.pos.z
bb.max.x += self.pos.x
bb.max.y += self.pos.y
bb.max.z += self.pos.z
return bb
def calc_collision_sphere(self):
centre_x = (self.bounding_box.max.x + self.bounding_box.min.x)/2
centre_y = (self.bounding_box.max.y + self.bounding_box.min.y)/2
centre_z = (self.bounding_box.max.z + self.bounding_box.min.z)/2
sphere = Sphere((centre_x, centre_y, centre_z), self.collision_radius, RED)
return sphere
def draw(self):
if not self.loaded:
self.load_data()
self.bounding_box = self.calc_bounding_box()
self.collision_sphere = self.calc_collision_sphere()
rl.DrawModelEx(self.model, self.pos, self.rotation_axis, self.rotation_angle, self.scale, self.color)
if self.wires:
rl.DrawBoundingBox(self.bounding_box, self.wire_color)
self.collision_sphere.draw()
def check_collision(self, other):
return self.collision_sphere.check_collision(other)
def run():
screen_width = 800
screen_height = 450
title = "RayLibPyZero"
if hasattr(mod, "WIDTH"):
screen_width = mod.WIDTH
if hasattr(mod, "HEIGHT"):
screen_height = mod.HEIGHT
if hasattr(mod, "TITLE"):
title = mod.TITLE
if hasattr(mod, "DATA_DIR"):
global data_dir
data_dir = mod.DATA_DIR
rl.SetConfigFlags(rl.FLAG_VSYNC_HINT + rl.FLAG_MSAA_4X_HINT)
rl.InitWindow(screen_width, screen_height, title.encode('utf-8'))
rl.SetTargetFPS(60)
if hasattr(mod, "CAMERA"):
rl.SetCameraMode(camera[0], mod.CAMERA)
if hasattr(mod, "init"):
mod.init()
while not rl.WindowShouldClose():
if hasattr(mod, "update"):
mod.update()
rl.UpdateCamera(camera)
if rl.IsKeyPressed(rl.KEY_F):
rl.ToggleFullscreen()
if rl.IsKeyPressed(rl.KEY_ESCAPE):
rl.Exit()
rl.BeginDrawing()
if hasattr(mod, "draw2dbackground"):
mod.draw2dbackground()
rl.BeginMode3D(camera[0])
if hasattr(mod, "draw3d"):
mod.draw3d()
rl.EndMode3D()
if hasattr(mod, "draw2d"):
mod.draw2d()
if hasattr(mod, "draw"):
mod.draw()
rl.EndDrawing()
rl.CloseWindow()
class Keyboard:
def __getattr__(self, kname):
# return is a reserved word, so alias enter to return
if kname == 'enter':
kname = 'return'
kname = kname.upper()
if not kname.startswith("KEY_"):
kname = "KEY_" + kname
return rl.IsKeyDown(getattr(rl, kname))
keyboard = Keyboard()