2019-08-14 17:19:01 +00:00
|
|
|
use crate::backend::render::ShapeHandle;
|
2019-07-19 08:32:41 +00:00
|
|
|
use crate::display_object::{DisplayObject, DisplayObjectBase};
|
2019-04-27 01:55:06 +00:00
|
|
|
use crate::player::{RenderContext, UpdateContext};
|
2019-08-14 17:19:01 +00:00
|
|
|
use crate::prelude::*;
|
2019-04-25 17:52:22 +00:00
|
|
|
|
2019-05-24 17:25:03 +00:00
|
|
|
#[derive(Clone)]
|
2019-08-13 02:00:12 +00:00
|
|
|
pub struct Graphic<'gc> {
|
|
|
|
base: DisplayObjectBase<'gc>,
|
2019-08-14 17:19:01 +00:00
|
|
|
static_data: gc_arena::Gc<'gc, GraphicStatic>,
|
2019-04-25 17:52:22 +00:00
|
|
|
}
|
|
|
|
|
2019-08-13 02:00:12 +00:00
|
|
|
impl<'gc> Graphic<'gc> {
|
2019-08-14 17:19:01 +00:00
|
|
|
pub fn from_swf_tag(context: &mut UpdateContext<'_, 'gc, '_>, swf_shape: &swf::Shape) -> Self {
|
|
|
|
let static_data = GraphicStatic {
|
|
|
|
id: swf_shape.id,
|
|
|
|
render_handle: context.renderer.register_shape(swf_shape),
|
|
|
|
bounds: swf_shape.shape_bounds.clone().into(),
|
|
|
|
};
|
2019-04-25 17:52:22 +00:00
|
|
|
Graphic {
|
2019-04-29 05:55:44 +00:00
|
|
|
base: Default::default(),
|
2019-08-14 17:19:01 +00:00
|
|
|
static_data: gc_arena::Gc::allocate(context.gc_context, static_data),
|
2019-04-25 17:52:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-13 02:00:12 +00:00
|
|
|
impl<'gc> DisplayObject<'gc> for Graphic<'gc> {
|
2019-05-07 10:34:17 +00:00
|
|
|
impl_display_object!(base);
|
2019-04-29 05:55:44 +00:00
|
|
|
|
2019-08-14 18:59:07 +00:00
|
|
|
fn local_bounds(&self) -> BoundingBox {
|
|
|
|
self.static_data.bounds.clone()
|
|
|
|
}
|
|
|
|
|
|
|
|
fn world_bounds(&self) -> BoundingBox {
|
|
|
|
let mut bounds = self.local_bounds().transform(self.matrix());
|
|
|
|
let mut node = self.parent();
|
|
|
|
while let Some(display_object) = node {
|
|
|
|
let display_object = display_object.read();
|
|
|
|
bounds = bounds.transform(display_object.matrix());
|
|
|
|
node = display_object.parent();
|
|
|
|
}
|
|
|
|
bounds
|
|
|
|
}
|
|
|
|
|
2019-04-26 03:27:44 +00:00
|
|
|
fn run_frame(&mut self, _context: &mut UpdateContext) {
|
2019-04-25 17:52:22 +00:00
|
|
|
// Noop
|
|
|
|
}
|
|
|
|
|
|
|
|
fn render(&self, context: &mut RenderContext) {
|
2019-08-14 18:59:07 +00:00
|
|
|
if !self.world_bounds().intersects(&context.view_bounds) {
|
|
|
|
// Off-screen; culled
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-05-01 16:55:54 +00:00
|
|
|
context.transform_stack.push(self.transform());
|
2019-04-26 21:11:29 +00:00
|
|
|
|
2019-08-14 17:19:01 +00:00
|
|
|
context.renderer.render_shape(
|
|
|
|
self.static_data.render_handle,
|
|
|
|
context.transform_stack.transform(),
|
|
|
|
);
|
2019-04-27 17:54:37 +00:00
|
|
|
|
2019-05-01 16:55:54 +00:00
|
|
|
context.transform_stack.pop();
|
2019-04-26 21:11:29 +00:00
|
|
|
}
|
2019-04-25 17:52:22 +00:00
|
|
|
}
|
2019-05-24 17:25:03 +00:00
|
|
|
|
2019-08-13 02:00:12 +00:00
|
|
|
unsafe impl<'gc> gc_arena::Collect for Graphic<'gc> {
|
2019-05-24 17:25:03 +00:00
|
|
|
#[inline]
|
|
|
|
fn needs_trace() -> bool {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
2019-08-14 17:19:01 +00:00
|
|
|
|
|
|
|
/// Static data shared between all instances of a graphic.
|
|
|
|
#[allow(dead_code)]
|
|
|
|
struct GraphicStatic {
|
|
|
|
id: CharacterId,
|
|
|
|
render_handle: ShapeHandle,
|
|
|
|
bounds: BoundingBox,
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe impl<'gc> gc_arena::Collect for GraphicStatic {
|
|
|
|
#[inline]
|
|
|
|
fn needs_trace() -> bool {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|