import random
from PySide6.QtCore import QPoint, QPointF
from PySide6.QtGui import QTransform, QPolygonF, QPixmap, QPen, QColor
from PySide6.QtWidgets import QGraphicsPixmapItem, QGraphicsEllipseItem
from BaseMod.LevelParts import PropLevelPart
from RWS.Core import lingoIO
from RWS.Loaders import Prop
from RWS.Renderable import Renderable, RenderPoly, Handle
from RWS.Utils import remap, rotate_point, point2polar
[docs]
class PropRenderable(Renderable):
[docs]
def __init__(self, module, prop: PropLevelPart.PlacedProp | Prop, add_renderable: bool = True):
self.hide = False
self.drawpoly = False
self._rotation = 0
self._beforetransform = []
if not isinstance(prop, Prop):
self.propdepth = prop.depth
super().__init__(module, -self.propdepth // 10 * 100 + 100, False)
self.poly = RenderPoly(module, self.depth, QPolygonF())
self.transform: list[QPointF] = prop.quad
self.prop = prop.prop
if self.prop.rope:
self.rope_segments = [QPointF(*lingoIO.fromarr(p, "point")) for p in prop.settings["points"]]
self.rope_graphics = [QGraphicsEllipseItem(i.x() - 5, i.y() - 5, 10, 10) for i in self.rope_segments]
self.previewcolor = QColor(*lingoIO.fromarr(self.prop.get("previewColor", QColor(255, 0, 0)), "color"))
variation = prop.settings["settings"].get("variation", 1) - 1
self.image = prop.prop.images[variation]
self.renderedtexture = QGraphicsPixmapItem(QPixmap.fromImage(self.image))
self.renderedtexture.setZValue(self.depth)
if add_renderable:
self.module.add_renderable(self)
return
self.prop = prop
self.image = prop.images[0]
super().__init__(module, 100, False)
self.poly = RenderPoly(module, 100, QPolygonF())
self.renderedtexture = QGraphicsPixmapItem(QPixmap.fromImage(self.image))
self.renderedtexture.setZValue(self.depth)
self.propdepth = 0
w, h = prop.images[0].width(), prop.images[0].height()
self.transform: list[QPointF] = [QPointF(0, 0), QPointF(w, 0), QPointF(w, h), QPointF(0, h)]
self.handles: list[Handle] = []
self.rope_graphics = []
self.rope_segments = []
self.previewcolor = QColor(255, 0, 0)
if add_renderable:
self.module.add_renderable(self)
[docs]
def create_rope_graphics_from_model(self, model):
if not self.prop.rope:
return
for i in self.rope_graphics:
self.viewport.workscene.removeItem(i)
self.previewcolor = QColor(*lingoIO.fromarr(self.prop.get("previewColor", "color(255, 0, 0)"), "color"))
self.rope_graphics = []
for i in model.segments:
pos = i["pos"]
self.rope_segments.append(pos)
self.rope_graphics.append(QGraphicsEllipseItem(0, 0, 10, 10))
self.rope_graphics[-1].setBrush(self.previewcolor)
color2 = self.previewcolor.__copy__()
color2.setAlpha(180)
self.rope_graphics[-1].setPen(color2)
self.viewport.workscene.addItem(self.rope_graphics[-1])
self.retransform()
[docs]
def set_variation(self, variation: int):
if variation == 0:
self.image = self.prop.images[random.randint(0, self.prop.vars - 1)]
self.renderedtexture.setPixmap(QPixmap.fromImage(self.image))
return
self.image = self.prop.images[variation - 1]
self.renderedtexture.setPixmap(QPixmap.fromImage(self.image))
[docs]
def setprop(self, prop: Prop):
self.prop = prop
self.image = prop.images[0]
w, h = prop.images[0].width(), prop.images[0].height()
self.transform: list[QPointF] = [QPointF(0, 0), QPointF(w, 0), QPointF(w, h), QPointF(0, h)]
if self.renderedtexture is not None:
self.renderedtexture.setPixmap(QPixmap.fromImage(self.image))
if len(self.handles) > 0:
self.delete_handlers()
self.free_transform()
self.retransform()
self.viewport.clean()
[docs]
def init_graphics(self, viewport):
super().init_graphics(viewport)
viewport.workscene.addItem(self.renderedtexture)
if self.prop.rope:
for i in self.rope_graphics:
viewport.workscene.addItem(i)
i.setBrush(self.previewcolor)
color2 = self.previewcolor.__copy__()
color2.setAlpha(180)
i.setPen(color2)
self.retransform()
#self.free_transform()
# self.poly.init_graphics(viewport)
[docs]
def remove_graphics(self, viewport):
super().remove_graphics(viewport)
viewport.workscene.removeItem(self.renderedtexture)
self.poly.remove_graphics(viewport)
if self.prop.rope:
for i in self.rope_graphics:
viewport.workscene.removeItem(i)
[docs]
def remove_myself(self):
super().remove_myself()
self.poly.remove_myself()
[docs]
def move_event(self):
super().move_event()
self.renderedtexture.setPos(self.actual_offset)
self.retransform()
[docs]
def zoom_event(self):
#self.renderedtexture.setScale(zoom)
self.retransform()
[docs]
def setPos(self, pos: QPointF):
super().setPos(pos)
self.renderedtexture.setPos(self.actual_offset)
self.retransform()
#self.renderedtexture.setScale(self.zoom)
[docs]
def delete_handlers(self):
for i in self.handles:
i.remove_graphics(self.viewport)
i.remove_myself()
self.handles.clear()
[docs]
def free_rotate(self):
self._beforetransform = [i.__copy__() for i in self.transform]
self.handles.append(Handle(self.module))
self._rotation = point2polar(self.transform[0]).x()
self.handles[0].setPos(self.transform[0] + self.offset)
self.handles[0].posChanged.connect(self.rotate)
[docs]
def rotate(self, point):
newpoint = point - self.offset
rotation = point2polar(newpoint).x() - self._rotation
for i, v in enumerate(self._beforetransform):
self.transform[i] = rotate_point(v, rotation)
self.retransform()
[docs]
def pointchange(self, i):
def p(v):
self.transform[i] = v - self.offset
self.retransform()
return p
[docs]
def set_visible(self, state):
self.hide = not state
self.retransform()
if self.prop.rope:
for i in self.rope_graphics:
i.setOpacity(1 if state else 0)
[docs]
def set_outline(self, state, outline):
self.drawpoly = state
self.poly.drawpoly.setPen(QPen(outline, 4))
self.retransform()