Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#72] Shirts #95

Merged
merged 26 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion resources/characters/characters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
pants:
style: Regular
color: Blue
shirt:
sleeve_style: Long
neckline: Crew
color: White
head:
ears:
type: Normal
Expand Down Expand Up @@ -164,6 +168,10 @@
pants:
style: Balloon
color: Red
shirt:
sleeve_style: Long
neckline: DeepV
color: Red
head:
ears:
type: Normal
Expand Down Expand Up @@ -221,7 +229,11 @@
clothing:
type: Simple
pants:
style: Regular
style: Shorts
color: Purple
shirt:
sleeve_style: None
neckline: Crew
color: Purple
head:
ears:
Expand Down Expand Up @@ -270,6 +282,10 @@
pants:
style: Regular
color: Gray
shirt:
sleeve_style: Short
neckline: Crew
color: Gray
head:
ears:
type: Normal
Expand Down
14 changes: 14 additions & 0 deletions resources/templates/appearance_edit.html.tera
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,20 @@
</li>
</ul>
</li>
<li>
<b>Shirt</b>
<ul>
<li>
<b>Sleeve Style:</b> {{ macros::add_select(name="appearance.body.clothing.shirt.sleeve_style", options=[ "Long","None","Short" ], selected=appearance.body.clothing.shirt.sleeve_style, update=true) }}
</li>
<li>
<b>Neckline:</b> {{ macros::add_select(name="appearance.body.clothing.shirt.neckline", options=[ "Boat","Crew","DeepV","None","Scoop","V" ], selected=appearance.body.clothing.shirt.neckline, update=true) }}
</li>
<li>
<b>Color:</b> {{ macros::add_select(name="appearance.body.clothing.shirt.color", options=[ "Aqua","Black","Blue","Fuchsia","Gray","Green","Lime","Maroon","Navy","Olive","Orange","Purple","Red","SaddleBrown","Silver","Teal","White","Yellow" ], selected=appearance.body.clothing.shirt.color, update=true) }}
</li>
</ul>
</li>
{% endif %}
</ul>
</li>
Expand Down
14 changes: 14 additions & 0 deletions resources/templates/character.html.tera
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,20 @@
</li>
</ul>
</li>
<li>
<b>Shirt</b>
<ul>
<li>
<b>Sleeve Style:</b> {{ appearance.body.clothing.shirt.sleeve_style }}
</li>
<li>
<b>Neckline:</b> {{ appearance.body.clothing.shirt.neckline }}
</li>
<li>
<b>Color:</b> {{ appearance.body.clothing.shirt.color }}
</li>
</ul>
</li>
{% endif %}
</ul>
</li>
Expand Down
3 changes: 3 additions & 0 deletions rpg_tools_core/src/model/equipment/appearance/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use crate::model::equipment::appearance::pants::Pants;
use crate::model::equipment::appearance::shirt::Shirt;
use macro_ui::ui;
use serde::{Deserialize, Serialize};

pub mod pants;
pub mod shirt;

#[derive(ui, Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "type")]
Expand All @@ -11,5 +13,6 @@ pub enum Clothing {
None,
Simple {
pants: Pants,
shirt: Shirt,
},
}
4 changes: 2 additions & 2 deletions rpg_tools_core/src/model/equipment/appearance/pants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ use macro_convert::Convert;
use macro_ui::ui;
use serde::{Deserialize, Serialize};

/// Clothing for the lower body.
/// The pants of the [`character`](crate::model::character::Character).
#[derive(ui, Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Pants {
pub style: PantsStyle,
pub color: Color,
}

/// What style of pants?
/// What style of [`pants`](Pants)?
#[derive(Convert, ui, Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum PantsStyle {
Balloon,
Expand Down
33 changes: 33 additions & 0 deletions rpg_tools_core/src/model/equipment/appearance/shirt.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use crate::model::color::Color;
use macro_convert::Convert;
use macro_ui::ui;
use serde::{Deserialize, Serialize};

/// The shirt of the [`character`](crate::model::character::Character).
#[derive(ui, Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct Shirt {
pub sleeve_style: SleeveStyle,
pub neckline: Neckline,
pub color: Color,
}

/// What style of neckline?
#[derive(Convert, ui, Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum Neckline {
Boat,
Crew,
DeepV,
#[default]
None,
Scoop,
V,
}

/// What style of sleeves?
#[derive(Convert, ui, Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub enum SleeveStyle {
#[default]
Long,
None,
Short,
}
11 changes: 6 additions & 5 deletions rpg_tools_rendering/examples/pants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ extern crate rpg_tools_rendering;

use crate::utils::render::render_2_sets;
use rpg_tools_core::model::character::appearance::body::{Body, BodyShape};
use rpg_tools_core::model::character::appearance::head::Head;
use rpg_tools_core::model::character::appearance::Appearance;
use rpg_tools_core::model::color::Color;
use rpg_tools_core::model::equipment::appearance::pants::{Pants, PantsStyle};
use rpg_tools_core::model::equipment::appearance::Clothing;
use rpg_tools_core::model::length::Length;
use rpg_tools_core::model::width::Width;

pub mod utils;

Expand Down Expand Up @@ -40,11 +38,14 @@ fn create_appearance(height: Length, pants: &Pants, shape: &BodyShape) -> Appear
Appearance::humanoid(
Body {
shape: *shape,
width: Width::default(),
width: Default::default(),
skin: Default::default(),
clothing: Clothing::Simple { pants: *pants },
clothing: Clothing::Simple {
pants: *pants,
shirt: Default::default(),
},
},
Head::default(),
Default::default(),
height,
)
}
50 changes: 50 additions & 0 deletions rpg_tools_rendering/examples/shirts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
extern crate rpg_tools_core;
extern crate rpg_tools_rendering;

use crate::utils::render::render_2_sets;
use rpg_tools_core::model::character::appearance::body::{Body, BodyShape};
use rpg_tools_core::model::character::appearance::Appearance;
use rpg_tools_core::model::color::Color;
use rpg_tools_core::model::equipment::appearance::shirt::{Neckline, Shirt, SleeveStyle};
use rpg_tools_core::model::equipment::appearance::Clothing;
use rpg_tools_core::model::length::Length;

pub mod utils;

fn main() {
let mut shirts = vec![];

for neckline in Neckline::get_all() {
for sleeve_style in SleeveStyle::get_all() {
shirts.push(Shirt {
sleeve_style,
neckline,
color: Color::Aqua,
})
}
}

render_2_sets(
"shirts.svg",
shirts,
BodyShape::get_all(),
create_appearance,
false,
);
}

fn create_appearance(height: Length, shirt: &Shirt, shape: &BodyShape) -> Appearance {
Appearance::humanoid(
Body {
shape: *shape,
width: Default::default(),
skin: Default::default(),
clothing: Clothing::Simple {
pants: Default::default(),
shirt: *shirt,
},
},
Default::default(),
height,
)
}
82 changes: 40 additions & 42 deletions rpg_tools_rendering/src/rendering/body/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::math::aabb2d::{get_end_x, get_start_x, AABB};
use crate::math::orientation::Orientation;
use crate::math::point2d::Point2d;
use crate::math::polygon2d::Polygon2d;
use crate::math::polygon2d::builder::Polygon2dBuilder;
use crate::math::size2d::Size2d;
use crate::renderer::{RenderOptions, Renderer};
use crate::rendering::body::torso::render_torso;
use crate::rendering::config::RenderConfig;
use crate::rendering::equipment::pants::interpolate;
use rpg_tools_core::model::character::appearance::body::Body;
use std::ops::Mul;

Expand All @@ -15,8 +16,7 @@ pub fn render_body(renderer: &mut dyn Renderer, config: &RenderConfig, aabb: &AA
let options = config.get_skin_options(&body.skin);

render_legs(renderer, config, aabb, body, &options);
render_arms(renderer, config, &aabb, body, &options);
render_hands(renderer, config, aabb, body, &options);
render_arms(renderer, config, aabb, body, &options);
render_torso(renderer, config, aabb, body, &options);
}

Expand Down Expand Up @@ -50,67 +50,65 @@ fn render_legs(
renderer.render_circle_arc(&right_foot_start, foot_radius, offset, angle, options);
}

fn render_hands(
renderer: &mut dyn Renderer,
config: &RenderConfig,
aabb: &AABB,
body: &Body,
options: &RenderOptions,
) {
pub fn render_hands(renderer: &mut dyn Renderer, config: &RenderConfig, aabb: &AABB, body: &Body) {
let options = config.get_skin_options(&body.skin);
let hand_radius = config.body.get_hand_radius(body, aabb);
let distance_between_hands = config.body.get_shoulder_width(body)
+ config.body.get_arm_width(body)
+ config.body.get_fat_offset_factor(body);
let distance_between_hands =
config.body.get_distance_between_hands(body) + config.body.get_hand_radius_factor(body);
let hand_y = config.body.get_arm_y() + config.body.height_arm;
let (left_hand_center, right_hand_center) =
aabb.get_mirrored_points(distance_between_hands, hand_y);

renderer.render_circle(&left_hand_center, hand_radius, options);
renderer.render_circle(&right_hand_center, hand_radius, options);
renderer.render_circle(&left_hand_center, hand_radius, &options);
renderer.render_circle(&right_hand_center, hand_radius, &options);
}

fn render_arms(
renderer: &mut dyn Renderer,
config: &RenderConfig,
aabb: &&AABB,
aabb: &AABB,
body: &Body,
options: &RenderOptions,
) {
let arm_size = aabb
.size()
.scale(config.body.get_arm_width(body), config.body.height_arm);
let arm_start_x = get_start_x(config.body.get_shoulder_width(body));
let right_arm_start = aabb.get_point(
arm_start_x - config.body.get_arm_width(body),
config.body.get_arm_y(),
);
let fat_offset = aabb.convert_to_height(config.body.get_fat_offset_factor(body) / 2.0);
let polygon = create_arm(arm_size, right_arm_start, fat_offset as i32);
let polygon = get_left_arm(config, aabb, body).build();

renderer.render_rounded_polygon(&polygon, options);
renderer.render_rounded_polygon(&aabb.mirrored(&polygon), options);
}

fn create_arm(arm_size: Size2d, right_arm_start: Point2d, offset: i32) -> Polygon2d {
let right_arm = AABB::new(right_arm_start, arm_size);
let mut polygon: Polygon2d = (&right_arm).into();

if offset != 0 {
let corners = polygon.corners_mut();

update_corner(corners, 2, offset);
update_corner(corners, 3, offset);
}
pub fn get_left_arm(config: &RenderConfig, aabb: &AABB, body: &Body) -> Polygon2dBuilder {
let mut builder = get_left_arm_short(config, aabb, body, false);
let width = config.body.get_arm_width(body);
let bottom_x = get_end_x(config.body.get_distance_between_hands(body));
let y = config.body.get_arm_y() + config.body.height_arm;

polygon.create_sharp_corner(1);
builder.add_point(aabb.get_point(bottom_x, y), false);
builder.add_point_cw(aabb.get_point(bottom_x + width, y), false);

polygon
builder
}

fn update_corner(corners: &mut [Point2d], index: usize, offset: i32) {
if let Some(p) = corners.get_mut(index) {
p.x -= offset;
}
pub fn get_left_arm_short(
config: &RenderConfig,
aabb: &AABB,
body: &Body,
bottom_sharp: bool,
) -> Polygon2dBuilder {
let mut builder = Polygon2dBuilder::new();
let width = config.body.get_arm_width(body);
let top_x = get_end_x(config.body.get_shoulder_width(body) * 0.94);
let bottom_x = get_end_x(config.body.get_distance_between_hands(body));
let bottom_x = interpolate(top_x, bottom_x, 0.7);
let y = config.body.get_arm_y();
let mid_y = y + 0.2;

builder.add_point(aabb.get_point(top_x, y), true);
builder.add_point_cw(aabb.get_point(top_x + width, y), false);
builder.add_point(aabb.get_point(top_x, y + 0.1), true);
builder.add_point(aabb.get_point(bottom_x, mid_y), bottom_sharp);
builder.add_point_cw(aabb.get_point(bottom_x + width, mid_y), bottom_sharp);

builder
}

fn render_leg(renderer: &mut dyn Renderer, options: &RenderOptions, start: Point2d, size: Size2d) {
Expand Down
Loading
Loading