Skip to content

Commit

Permalink
Extract and show sophie item images
Browse files Browse the repository at this point in the history
  • Loading branch information
holly-hacker committed Oct 27, 2023
1 parent dfb2a41 commit 164fab6
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 3 deletions.
2 changes: 2 additions & 0 deletions data-prepper/src/ryza3/extract_images/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub fn extract_images(
subdirectory: "enemies",
sprite_dimensions: (512, 512),
texture_atlas_dimensions: (64, 64),
..Default::default()
};
extract_sprites_with_texture_atlas(args, pak_index, output_directory, options)
.context("extract monster portraits")?;
Expand All @@ -37,6 +38,7 @@ pub fn extract_images(
subdirectory: "items",
sprite_dimensions: (512, 512),
texture_atlas_dimensions: (64, 64),
..Default::default()
};
extract_sprites_with_texture_atlas(args, pak_index, output_directory, options)
.context("extract item icons")?;
Expand Down
4 changes: 3 additions & 1 deletion data-prepper/src/sophie/extract_images/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ pub fn extract_images(
pattern: r"\Data\Win32\ui_JP\a17_item_l_*.g1t",
subdirectory: "items",
sprite_dimensions: (512, 512),
texture_atlas_dimensions: (64, 64),
sprite_trimmed_dimensions: Some((288, 288)),
// TODO: do we want 64 instead? we can only do integer scaling for now
texture_atlas_dimensions: (72, 72),
};
extract_sprites_with_texture_atlas(args, pak_index, output_directory, options)
.context("extract item icons")?;
Expand Down
14 changes: 13 additions & 1 deletion data-prepper/src/utils/images/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::extract_images::Args;
pub mod rgba8_image;
pub mod texture_atlas;

#[derive(Default)]
pub struct ExtractSpritesOptions {
/// The pattern used to find file names
pub pattern: &'static str,
Expand All @@ -19,6 +20,8 @@ pub struct ExtractSpritesOptions {
pub subdirectory: &'static str,
/// The size of each individual input image.
pub sprite_dimensions: (u32, u32),
/// The size of the image after optional trimming. If not present, no trimming is done.
pub sprite_trimmed_dimensions: Option<(u32, u32)>,
/// The size of each item in the texture atlas
pub texture_atlas_dimensions: (u32, u32),
}
Expand Down Expand Up @@ -47,7 +50,9 @@ pub fn extract_sprites_with_texture_atlas(

// create texture atlas
let mut texture_atlas = UniformTextureAtlas::new_with_scaling(
options.sprite_dimensions,
options
.sprite_trimmed_dimensions
.unwrap_or(options.sprite_dimensions),
options.texture_atlas_dimensions,
entries.len(),
)
Expand Down Expand Up @@ -78,6 +83,13 @@ pub fn extract_sprites_with_texture_atlas(
let image = Rgba8Image::new(texture.width, image_bytes).context("image buffer to image")?;
debug_assert_eq!(image.height(), texture.height);

// cut image if needed
let image = if let Some(trimmed_dimensions) = options.sprite_trimmed_dimensions {
image.trim_to(trimmed_dimensions.0, trimmed_dimensions.1)?
} else {
image
};

debug!(?entry, "adding image to texture atlas");
texture_atlas
.add_image(&image, num.to_string())
Expand Down
11 changes: 11 additions & 0 deletions data-prepper/src/utils/images/rgba8_image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,17 @@ impl Rgba8Image {
new_image
}

pub fn trim_to(&self, new_width: u32, new_height: u32) -> anyhow::Result<Self> {
if new_width > self.width() {
bail!("new width must be less than or equal to current width");
}
if new_height > self.height() {
bail!("new height must be less than or equal to current height");
}

self.copy_chunk(0, 0, new_width, new_height)
}

/// Copies a chunk of the image into a new image.
pub fn copy_chunk(&self, x: u32, y: u32, width: u32, height: u32) -> anyhow::Result<Self> {
if width == 0 {
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/data/sophie_data.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type TextureAtlasTypes from "@/data/types/texture_atlas.d.ts";
import type SophieTypes from "@/data/types/sophie.d.ts";
import { createContext } from "react";

export const SophieContext = createContext(null as unknown as SophieData);

export type SophieData = {
items_texture_atlas: TextureAtlasTypes.UniformTextureAtlasInfo,
items: SophieTypes.Item[],
present_info: SophieTypes.PresentInfo,
rumors: SophieTypes.Rumor[],
Expand All @@ -14,18 +16,21 @@ export async function getSophieData(): Promise<SophieData> {
const url_base = `${import.meta.env.VITE_DATA_URL}/sophie`;

const [
items_texture_atlas,
items,
present_info,
rumors,
dolls,
] = await Promise.all([
fetch(`${url_base}/texture-atlasses/items.json`).then(res => res.json()),
fetch(`${url_base}/items.json`).then(res => res.json()),
fetch(`${url_base}/presents.json`).then(res => res.json()),
fetch(`${url_base}/rumors.json`).then(res => res.json()),
fetch(`${url_base}/dolls.json`).then(res => res.json()),
]);

return {
items_texture_atlas,
items,
present_info,
rumors,
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/routes/sophie/items/detail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import types from "@/data/types/sophie";
import { useContext } from "react";
import { useParams } from "react-router-dom";
import { CategoryLink } from "../utility_components/links";
import { itemDisplayName } from "../sophie_data_util";
import { getImageLink, itemDisplayName } from "../sophie_data_util";

export default function ItemDetail(): JSX.Element {
const sophieData = useContext(SophieContext);
Expand All @@ -26,6 +26,9 @@ export default function ItemDetail(): JSX.Element {
return (
<>
<h1>{itemDisplayName(item)}</h1>
{item.img_no !== null && item.image_no >= 0 && (
<img src={getImageLink(`items/${item.image_no}.png`)}></img>
)}
<ItemDetailSection item={item} />
</>
);
Expand Down
15 changes: 15 additions & 0 deletions frontend/src/routes/sophie/items/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import types from "@/data/types/sophie";
import { ColumnDef, createColumnHelper } from "@tanstack/react-table";
import { useContext } from "react";
import { ItemLink } from "../utility_components/links";
import { TextureAtlasImage } from "@/routes/sophie/utility_components/links";

export default function ItemList(): JSX.Element {
const sophieData = useContext(SophieContext);
Expand All @@ -24,6 +25,20 @@ export default function ItemList(): JSX.Element {
function getColumnDefs(sophieData: SophieData): ColumnDef<types.Item, any>[] {
const columnHelper = createColumnHelper<(typeof sophieData.items)[0]>();
return [
columnHelper.accessor("image_no", {
header: "Image",
cell: (i) => {
return (
<ItemLink item={i.row.original}>
<TextureAtlasImage
texture_atlas={sophieData.items_texture_atlas}
texture_atlas_name="items"
name={String(i.getValue())}
/>
</ItemLink>
);
},
}),
columnHelper.accessor("name", {
header: "Name",
cell: (i) => <ItemLink item={i.row.original} />,
Expand Down
31 changes: 31 additions & 0 deletions frontend/src/routes/sophie/utility_components/links.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import types from "@/data/types/sophie";
import texture_atlas from "@/data/types/texture_atlas";
import { Link } from "react-router-dom";
import {
findItemByTag,
Expand Down Expand Up @@ -60,3 +61,33 @@ export function CategoryLink({
</Link>
);
}

export function TextureAtlasImage({
texture_atlas,
texture_atlas_name,
name, // TODO: accept dimensions as parameter too
}: {
texture_atlas: texture_atlas.UniformTextureAtlasInfo;
texture_atlas_name: string;
name: string;
}) {
const index = texture_atlas.stored_images.indexOf(name);
const x_index = index % texture_atlas.columns;
const y_index = Math.floor(index / texture_atlas.columns);

return (
<span
style={{
display: "inline-block",
height: texture_atlas.image_dimensions[0],
width: texture_atlas.image_dimensions[1],
backgroundImage: `url(${
import.meta.env.VITE_DATA_URL
}/sophie/${texture_atlas_name}/packed.webp)`,
backgroundPositionX: -x_index * texture_atlas.image_dimensions[0],
backgroundPositionY: -y_index * texture_atlas.image_dimensions[1],
backgroundRepeat: "no-repeat",
}}
></span>
);
}

0 comments on commit 164fab6

Please sign in to comment.