mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
basic text renderer implemented
This commit is contained in:
parent
68672f0112
commit
c76cbcb7d0
10 changed files with 277 additions and 167 deletions
|
@ -20,8 +20,8 @@
|
|||
"recoil": "0.0.10",
|
||||
"three": "^0.119.1",
|
||||
"three-plain-animator": "^1.0.2",
|
||||
"typescript": "^3.7.5",
|
||||
"ts-node": "^9.0.0"
|
||||
"ts-node": "^9.0.0",
|
||||
"typescript": "^3.7.5"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
|
|
|
@ -123,7 +123,7 @@ const BlueOrb = memo((props: BlueOrbContructorProps) => {
|
|||
<a.mesh
|
||||
position={props.position as [number, number, number]}
|
||||
rotation-y={props.rotation[1]}
|
||||
scale={[0.25, 0.15, 0.25]}
|
||||
scale={[0.36, 0.2, 0.36]}
|
||||
renderOrder={1}
|
||||
>
|
||||
<planeBufferGeometry attach="geometry" />
|
||||
|
|
|
@ -11,6 +11,7 @@ import { a, useSpring } from "@react-spring/three";
|
|||
import { useRecoilValue } from "recoil";
|
||||
import { hudActiveAtom } from "./HUDElementAtom";
|
||||
import { currentHUDAtom } from "./HUDElementAtom";
|
||||
import HUDText from "./HUDText";
|
||||
|
||||
export type HUDElementProps = {
|
||||
hudVisibility: boolean;
|
||||
|
@ -127,9 +128,7 @@ const HUDElement = memo((props: HUDElementProps) => {
|
|||
<group visible={props.hudVisibility} renderOrder={1}>
|
||||
<a.sprite
|
||||
position-x={longHUDPosX}
|
||||
position-y={
|
||||
currentBlueOrbHUD["long"]["position"][1]
|
||||
}
|
||||
position-y={currentBlueOrbHUD["long"]["position"][1]}
|
||||
position-z={currentBlueOrbHUD["long"]["position"][2]}
|
||||
scale={currentBlueOrbHUD["long"]["scale"] as [number, number, number]}
|
||||
>
|
||||
|
@ -141,9 +140,7 @@ const HUDElement = memo((props: HUDElementProps) => {
|
|||
</a.sprite>
|
||||
<a.sprite
|
||||
position-x={boringHUDPosX}
|
||||
position-y={
|
||||
currentBlueOrbHUD!["boring"]["position"][1]
|
||||
}
|
||||
position-y={currentBlueOrbHUD!["boring"]["position"][1]}
|
||||
position-z={currentBlueOrbHUD!["boring"]["position"][2]}
|
||||
scale={
|
||||
currentBlueOrbHUD!["boring"]["scale"] as [number, number, number]
|
||||
|
@ -157,9 +154,7 @@ const HUDElement = memo((props: HUDElementProps) => {
|
|||
</a.sprite>
|
||||
<a.sprite
|
||||
position-x={bigHUDPosX}
|
||||
position-y={
|
||||
currentBlueOrbHUD!["big"]["position"][1]
|
||||
}
|
||||
position-y={currentBlueOrbHUD!["big"]["position"][1]}
|
||||
position-z={currentBlueOrbHUD!["big"]["position"][2]}
|
||||
scale={currentBlueOrbHUD!["big"]["scale"] as [number, number, number]}
|
||||
>
|
||||
|
@ -169,6 +164,7 @@ const HUDElement = memo((props: HUDElementProps) => {
|
|||
transparent={true}
|
||||
/>
|
||||
</a.sprite>
|
||||
<HUDText text={"Tda028"} hudTextPos={[-0.35, 0.23, -8.7]} />
|
||||
</group>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -9,7 +9,7 @@ export const hudActiveAtom = atom({
|
|||
|
||||
export const hudVisibilityAtom = atom({
|
||||
key: "hudVisibilityAtom",
|
||||
default: false,
|
||||
default: true,
|
||||
});
|
||||
|
||||
export const currentHUDAtom = atom({
|
||||
|
|
27
src/components/HUD/HUDText.tsx
Normal file
27
src/components/HUD/HUDText.tsx
Normal file
|
@ -0,0 +1,27 @@
|
|||
import React from "react";
|
||||
import orange_font_json from "../../resources/orange_font.json";
|
||||
import Letter from "../TextRenderer";
|
||||
|
||||
type HUDTextProps = {
|
||||
text: string;
|
||||
hudTextPos: number[];
|
||||
};
|
||||
|
||||
const HUDText = (props: HUDTextProps) => {
|
||||
return (
|
||||
<group position={props.hudTextPos as [number, number, number]} scale={[0.04, 0.06, 0.04]}>
|
||||
{props.text.split("").map((letter: string, idx: number) => {
|
||||
return (
|
||||
<Letter
|
||||
color={"yellow"}
|
||||
letter={letter}
|
||||
kerningOffset={idx}
|
||||
key={idx}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</group>
|
||||
);
|
||||
};
|
||||
|
||||
export default HUDText;
|
|
@ -58,7 +58,6 @@ const MainScene = () => {
|
|||
position-z={3}
|
||||
position-y={cameraState.camPosY}
|
||||
rotation-y={cameraState.camRotY}
|
||||
aspect={-1}
|
||||
>
|
||||
<Suspense fallback={null}>
|
||||
<MainSceneIntro />
|
||||
|
|
|
@ -46,7 +46,6 @@ const OrthoCamera = memo(() => {
|
|||
>
|
||||
<HUDElement key={1} hudVisibility={hudVisible} />
|
||||
<Orb orbVisibility={orbVisible} />
|
||||
{/*<TextRenderer />*/}
|
||||
</a.orthographicCamera>
|
||||
</a.group>
|
||||
);
|
||||
|
|
|
@ -22,20 +22,20 @@ const Site = memo(() => {
|
|||
<>
|
||||
<Suspense fallback={<>loading...</>}>
|
||||
{/* distance between LEVELS is 1.5 */}
|
||||
{Object.values(level_y_values).map((yVal) => {
|
||||
return <Level levelPosY={yVal} key={yVal} />;
|
||||
})}
|
||||
{/*{Object.values(level_y_values).map((yVal) => {*/}
|
||||
{/* return <Level levelPosY={yVal} key={yVal} />;*/}
|
||||
{/*})}*/}
|
||||
|
||||
{Array.from(Array(8).keys()).map((colIdx: number) => {
|
||||
return (
|
||||
<Column
|
||||
columnData={siteData.siteA.filter((blueOrb) =>
|
||||
siteData.columnJson[colIdx].includes(blueOrb[0].substr(2))
|
||||
)}
|
||||
key={colIdx}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
{/*{Array.from(Array(8).keys()).map((colIdx: number) => {*/}
|
||||
{/* return (*/}
|
||||
{/* <Column*/}
|
||||
{/* columnData={siteData.siteA.filter((blueOrb) =>*/}
|
||||
{/* siteData.columnJson[colIdx].includes(blueOrb[0].substr(2))*/}
|
||||
{/* )}*/}
|
||||
{/* key={colIdx}*/}
|
||||
{/* />*/}
|
||||
{/* );*/}
|
||||
{/*})}*/}
|
||||
</Suspense>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -1,22 +1,111 @@
|
|||
import { useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import { RepeatWrapping } from "three";
|
||||
import orangeFont from "../static/sprites/orange_font_texture.png";
|
||||
import yellowFont from "../static/sprites/yellow_font_texture.png";
|
||||
import orange_font_json from "../resources/orange_font.json";
|
||||
import React from "react";
|
||||
import { a } from "@react-spring/three";
|
||||
import React, { useMemo } from "react";
|
||||
|
||||
const TextRenderer = () => {
|
||||
const orangeFontTexture: THREE.Texture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
orangeFont
|
||||
);
|
||||
type LetterProps = {
|
||||
color: string;
|
||||
letter: string;
|
||||
kerningOffset: number;
|
||||
};
|
||||
|
||||
type LineYOffsets = {
|
||||
[line: number]: number;
|
||||
};
|
||||
|
||||
type ColorToTexture = {
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
type LetterData = {
|
||||
[letter: string]: number[];
|
||||
};
|
||||
|
||||
type BigFontData = {
|
||||
kerning: number;
|
||||
baseline: number;
|
||||
height: number;
|
||||
glyphs: LetterData;
|
||||
};
|
||||
|
||||
const Letter = (props: LetterProps) => {
|
||||
const colorToTexture = (color: string) => {
|
||||
return ({ orange: orangeFont, yellow: yellowFont } as ColorToTexture)[
|
||||
color
|
||||
];
|
||||
};
|
||||
|
||||
// first letter in big font is always orange in this case so make it orange if so. else,
|
||||
// run through the function.
|
||||
const color =
|
||||
props.kerningOffset === 0 ? orangeFont : colorToTexture(props.color);
|
||||
|
||||
const colorTexture: THREE.Texture = useLoader(THREE.TextureLoader, color);
|
||||
|
||||
// i have yet to figure out a genrealizable way of
|
||||
// calculating the y offset, this shit will do for now
|
||||
// also, we dont have all the lines since i dont need them yet.
|
||||
// also, baseline offsets dont work properly since i dont need them yet either
|
||||
// should be trivial to calculate though, im just lazy
|
||||
const getLineNum = (letter: string) => {
|
||||
const lineOne = "ABCDEFGHIJKLMNOPQ";
|
||||
const lineTwo = "RSTUVWXYZ01234567";
|
||||
const lineThree = "89abcdefghijklmnopqrs";
|
||||
|
||||
if (lineOne.includes(letter)) {
|
||||
return 1;
|
||||
} else if (lineTwo.includes(letter)) {
|
||||
return 2;
|
||||
} else {
|
||||
return 3;
|
||||
}
|
||||
};
|
||||
|
||||
const lineYOffsets: LineYOffsets = {
|
||||
1: 0.884,
|
||||
2: 0.765,
|
||||
3: 0.65,
|
||||
};
|
||||
|
||||
const letterData = (orange_font_json as BigFontData)["glyphs"][props.letter];
|
||||
|
||||
const geometry = new THREE.PlaneBufferGeometry();
|
||||
|
||||
const uvAttribute = geometry.attributes.uv;
|
||||
|
||||
for (let i = 0; i < uvAttribute.count; i++) {
|
||||
let u = uvAttribute.getX(i);
|
||||
let v = uvAttribute.getY(i);
|
||||
|
||||
u = (u * letterData[2]) / 256 + letterData[0] / 256;
|
||||
|
||||
v =
|
||||
(v * letterData[3]) / 136 +
|
||||
letterData[4] / 136 +
|
||||
lineYOffsets[getLineNum(props.letter)] -
|
||||
letterData[4] / 136;
|
||||
|
||||
uvAttribute.setXY(i, u, v);
|
||||
}
|
||||
|
||||
return (
|
||||
<group position={[0, 0, -9]}>
|
||||
<sprite>
|
||||
<spriteMaterial attach="material" map={orangeFontTexture} />
|
||||
</sprite>
|
||||
</group>
|
||||
<a.mesh
|
||||
position-x={
|
||||
props.kerningOffset === 0
|
||||
? props.kerningOffset
|
||||
: props.kerningOffset + 0.3
|
||||
}
|
||||
position-y={props.kerningOffset === 0 ? -0.03 : 0}
|
||||
scale={props.kerningOffset === 0 ? [1.7, 1, 1.7] : [1, 1, 1]}
|
||||
geometry={geometry}
|
||||
>
|
||||
<meshBasicMaterial map={colorTexture} attach="material" transparent={true} />
|
||||
</a.mesh>
|
||||
);
|
||||
};
|
||||
|
||||
export default TextRenderer;
|
||||
export default Letter;
|
||||
|
|
|
@ -13,16 +13,16 @@
|
|||
},
|
||||
|
||||
"14": {
|
||||
"position": [-0.35, 0, 1.3],
|
||||
"rotation": [0, -0.15, 0]
|
||||
"position": [-0.5, 0, 1.1],
|
||||
"rotation": [0, -0.23, 0]
|
||||
},
|
||||
"22": {
|
||||
"position": [-0.35, 0.3, 1.3],
|
||||
"rotation": [0, -0.15, 0]
|
||||
"position": [-0.5, 0.4, 1.1],
|
||||
"rotation": [0, -0.23, 0]
|
||||
},
|
||||
"06": {
|
||||
"position": [-0.35, -0.3, 1.3],
|
||||
"rotation": [0, -0.15, 0]
|
||||
"position": [-0.5, -0.4, 1.1],
|
||||
"rotation": [0, -0.23, 0]
|
||||
},
|
||||
|
||||
"07": {
|
||||
|
|
Loading…
Reference in a new issue