This commit is contained in:
zjt 2024-06-24 16:03:17 +08:00
parent 6494149f9f
commit dc2ddc3fa4
19 changed files with 11871 additions and 121 deletions

View File

@ -1,4 +1,11 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};
const nextConfig = {
typescript: {
ignoreBuildErrors: true,
},
eslint: {
ignoreDuringBuilds: true,
}
};
export default nextConfig;

View File

@ -9,16 +9,19 @@
"lint": "next lint"
},
"dependencies": {
"axios": "^1.7.2",
"next": "14.2.4",
"pixi-live2d-display": "^0.4.0",
"pixi.js": "6.4.2",
"react": "^18",
"react-dom": "^18",
"next": "14.2.4"
"react-dom": "^18"
},
"devDependencies": {
"typescript": "^5",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"postcss": "^8",
"tailwindcss": "^3.4.1"
"tailwindcss": "^3.4.1",
"typescript": "^5"
}
}

210
src/app/helper.tsx Normal file
View File

@ -0,0 +1,210 @@
"use client"
import dynamic from 'next/dynamic';
import { useEffect, useRef, useState } from 'react';
import '@/deps/live2d.min.js'
import useVoice2Txt from "@/hooks/useVoice2txt";
import useTxt2Voice from '@/hooks/useTxt2Voice';
import axios from 'axios';
import * as PIXI from 'pixi.js';
import { Live2DModel } from 'pixi-live2d-display/cubism2';
//import "@/deps/live2dcubismcore.min.js"
export default function Home() {
function draggable(model: any) {
model.buttonMode = true;
model.on("pointerdown", (e: any) => {
model.dragging = true;
model._pointerX = e.data.global.x - model.x;
model._pointerY = e.data.global.y - model.y;
});
model.on("pointermove", (e: any) => {
if (model.dragging) {
model.position.x = e.data.global.x - model._pointerX;
model.position.y = e.data.global.y - model._pointerY;
}
});
model.on("pointerupoutside", () => (model.dragging = false));
model.on("pointerup", () => (model.dragging = false));
}
function addFrame(model: any) {
const foreground = PIXI.Sprite.from(PIXI.Texture.WHITE);
foreground.width = model.internalModel.width;
foreground.height = model.internalModel.height;
foreground.alpha = 0.2;
model.addChild(foreground);
checkbox("Model Frames", (checked: any) => (foreground.visible = checked));
}
function addHitAreaFrames(model: any) {
try {
//@ts-ignore
const hitAreaFrames = new PIXI.live2d.HitAreaFrames();
model.addChild(hitAreaFrames);
checkbox("Hit Area Frames", (checked: any) => (hitAreaFrames.visible = checked));
} catch (err) {
}
}
function checkbox(name: any, onChange: any) {
const id = name.replace(/\W/g, "").toLowerCase();
let checkbox = document.getElementById(id);
if (!checkbox) {
const p = document.createElement("p")!;
p.innerHTML = `<input type="checkbox" id="${id}"> <label for="${id}">${name}</label>`;
document!.getElementById("control")!.appendChild(p);
checkbox = p.firstChild as HTMLElement;
}
checkbox.addEventListener("change", () => {
//@ts-ignore
onChange(checkbox.checked);
});
//@ts-ignore
onChange(checkbox.checked);
}
const send = (inputText: string) => {
if (!inputText) return;
console.log(inputText)
let data = JSON.stringify({
"messages": [
{
"content": `回答用户的问题,尽可能简短。`,
"role": "system"
},
{
"content": inputText,
"role": "user"
}
],
"model": "deepseek-chat",
"frequency_penalty": 0,
"max_tokens": 2048,
"presence_penalty": 0,
"stop": null,
"stream": false,
"temperature": 1,
"top_p": 1
});
let config = {
method: 'post',
maxBodyLength: Infinity,
url: 'https://api.deepseek.com/chat/completions',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'Authorization': 'Bearer sk-dd24ae704e8d4939aeed8f050d04d36b'
},
data: data
};
axios(config)
.then((response) => {
console.log(`response`, response);
console.log(response.data);
speak(response.data.choices[0].message.content);
setResponse(response.data.choices[0].message.content);
})
.catch((error) => {
console.log(error);
});
}
const { start, end, text, isListening } = useVoice2Txt({
lang: 'cmn-Hans-CN',
continuous: false
});
const {
isSpeaking,
speak,
stop
} = useTxt2Voice();
const [inputText, setInputText] = useState("");
const isMouthOpen = useRef(false);
const [response, setResponse] = useState("");
useEffect(() => {
console.log(text)
if (!text) return;
send(text);
}, [text]);
const [model, setModel] = useState<Live2DModel>();
useEffect(() => {
if (!isSpeaking) {
isMouthOpen.current = false;
}
}, [isSpeaking]);
useEffect(() => {
if (!isListening && !isSpeaking) { }
}, [isListening]);
useEffect(() => {
// expose PIXI to window so that this plugin is able to
// reference window.PIXI.Ticker to automatically update Live2D models
//@ts-ignore
typeof window !== 'undefined' && (window.PIXI = PIXI);
(async function () {
const app = new PIXI.Application({
view: document.getElementById('canvas') as HTMLCanvasElement,
});
const model = await Live2DModel.from('https://cdn.jsdelivr.net/gh/guansss/pixi-live2d-display/test/assets/shizuku/shizuku.model.json');
app.stage.addChild(model);
const scaleX = (innerWidth * 0.4) / model.width;
const scaleY = (innerHeight * 0.8) / model.height;
// fit the window
model.scale.set(0.3);
model.y = innerHeight * 0.1;
draggable(model);
addFrame(model);
addHitAreaFrames(model);
setModel(model);
model.on('hit', (hitAreas) => {
if (hitAreas.includes('body')) {
model.motion('tap_body');
model.motion('speak')
}
});
})();
}, [])
return (
<main>
{
typeof window !== 'undefined'
&& typeof window.Live2D !== 'undefined'
&& (<div className='flex w-full flex-col h-full items-center justify-center relative'>
<canvas className='w-[40%] h-[40%]' id="canvas"></canvas>
<div className='absolute right-[20vw] top-4 bg-white rounded w-[20vw] h-auto text-sm text-black'>{response ? response : "请输入文字和我聊天吧"}</div>
<div id="control"></div>
<button onClick={start}></button>
<button onClick={end}></button>
<input className='text-black' value={inputText} onChange={(e) => {
setInputText(e.target.value);
console.log(e.target.value)
}}></input>
<button onClick={() => {
send(inputText);
setInputText("");
}}></button>
</div>)
}
</main>
);
}

View File

@ -1,8 +1,6 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Create Next App",
@ -16,7 +14,10 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
<head>
{/* <script src="http://publicjs.supmiao.com/live2dcubismcore.min.js"></script> */}
</head>
<body>{children}</body>
</html>
);
}

View File

@ -1,113 +1,9 @@
import Image from "next/image";
"use client"
import dynamic from "next/dynamic";
const Page = dynamic(() => import('./helper'), {
ssr: false
})
//import "@/deps/live2dcubismcore.min.js"
export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div className="z-10 w-full max-w-5xl items-center justify-between font-mono text-sm lg:flex">
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
Get started by editing&nbsp;
<code className="font-mono font-bold">src/app/page.tsx</code>
</p>
<div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:size-auto lg:bg-none">
<a
className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
By{" "}
<Image
src="/vercel.svg"
alt="Vercel Logo"
className="dark:invert"
width={100}
height={24}
priority
/>
</a>
</div>
</div>
<div className="relative z-[-1] flex place-items-center before:absolute before:h-[300px] before:w-full before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-full after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 sm:before:w-[480px] sm:after:w-[240px] before:lg:h-[360px]">
<Image
className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert"
src="/next.svg"
alt="Next.js Logo"
width={180}
height={37}
priority
/>
</div>
<div className="mb-32 grid text-center lg:mb-0 lg:w-full lg:max-w-5xl lg:grid-cols-4 lg:text-left">
<a
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
target="_blank"
rel="noopener noreferrer"
>
<h2 className="mb-3 text-2xl font-semibold">
Docs{" "}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className="m-0 max-w-[30ch] text-sm opacity-50">
Find in-depth information about Next.js features and API.
</p>
</a>
<a
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
target="_blank"
rel="noopener noreferrer"
>
<h2 className="mb-3 text-2xl font-semibold">
Learn{" "}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className="m-0 max-w-[30ch] text-sm opacity-50">
Learn about Next.js in an interactive course with&nbsp;quizzes!
</p>
</a>
<a
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
target="_blank"
rel="noopener noreferrer"
>
<h2 className="mb-3 text-2xl font-semibold">
Templates{" "}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className="m-0 max-w-[30ch] text-sm opacity-50">
Explore starter templates for Next.js.
</p>
</a>
<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
target="_blank"
rel="noopener noreferrer"
>
<h2 className="mb-3 text-2xl font-semibold">
Deploy{" "}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className="m-0 max-w-[30ch] text-balance text-sm opacity-50">
Instantly deploy your Next.js site to a shareable URL with Vercel.
</p>
</a>
</div>
</main>
);
return <Page />
}

5148
src/deps/live2d.min.js vendored Normal file

File diff suppressed because it is too large Load Diff

367
src/deps/live2dcubismcore.d.ts vendored Normal file
View File

@ -0,0 +1,367 @@
/**
* Copyright(c) Live2D Inc. All rights reserved.
*
* Use of this source code is governed by the Live2D Proprietary Software license
* that can be found at https://www.live2d.com/eula/live2d-proprietary-software-license-agreement_en.html.
*/
declare namespace Live2DCubismCore {
/** Cubism version identifier. */
type csmVersion = number;
/** moc3 version identifier. */
type csmMocVersion = number;
/** Parameter type identifier. */
type csmParameterType = number;
/** Necessary alignment for mocs (in bytes). */
const AlignofMoc: number;
/** Necessary alignment for models (in bytes). */
const AlignofModel: number;
/** .moc3 file version Unknown */
const MocVersion_Unknown: number;
/** .moc3 file version 3.0.00 - 3.2.07 */
const MocVersion_30: number;
/** .moc3 file version 3.3.00 - 3.3.03 */
const MocVersion_33: number;
/** .moc3 file version 4.0.00 - 4.1.05 */
const MocVersion_40: number;
/** .moc3 file version 4.2.00 - 4.2.04 */
const MocVersion_42: number;
/** .moc3 file version 5.0.00 - */
const MocVersion_50: number;
/** Normal Parameter. */
const ParameterType_Normal: number;
/** Parameter for blend shape. */
const ParameterType_BlendShape: number;
/** Log handler.
*
* @param message Null-terminated string message to log.
*/
interface csmLogFunction {
(message: string): void;
}
/** Cubism version. */
class Version {
/**
* Queries Core version.
*
* @return Core version.
*/
static csmGetVersion(): csmVersion;
/**
* Gets Moc file supported latest version.
*
* @return Moc file latest format version.
*/
static csmGetLatestMocVersion(): csmMocVersion;
/**
* Gets Moc file format version.
*
* @param moc Moc
*
* @return csmMocVersion
*/
static csmGetMocVersion(moc: Moc, mocBytes: ArrayBuffer): csmMocVersion;
private constructor();
}
/** Cubism logging. */
class Logging {
private static logFunction;
/**
* Sets log handler.
*
* @param handler Handler to use.
*/
static csmSetLogFunction(handler: csmLogFunction): void;
/**
* Queries log handler.
*
* @return Log handler.
*/
static csmGetLogFunction(): csmLogFunction;
/**
* Wrap log function.
*
* @param messagePtr number
*
* @return string
*/
private static wrapLogFunction;
private constructor();
}
/** Cubism moc. */
class Moc {
/**
* Checks consistency of a moc.
*
* @param mocBytes Moc bytes.
*
* @returns '1' if Moc is valid; '0' otherwise.
*/
hasMocConsistency(mocBytes: ArrayBuffer): number;
/** Creates [[Moc]] from [[ArrayBuffer]].
*
* @param buffer Array buffer
*
* @return [[Moc]] on success; [[null]] otherwise.
*/
static fromArrayBuffer(buffer: ArrayBuffer): Moc;
/** Releases instance. */
_release(): void;
/** Native moc. */
_ptr: number;
/**
* Initializes instance.
*
* @param mocBytes Moc bytes.
*/
private constructor();
}
/** Cubism model. */
class Model {
/** Parameters. */
parameters: Parameters;
/** Parts. */
parts: Parts;
/** Drawables. */
drawables: Drawables;
/** Canvas information. */
canvasinfo: CanvasInfo;
/**
* Creates [[Model]] from [[Moc]].
*
* @param moc Moc
*
* @return [[Model]] on success; [[null]] otherwise.
*/
static fromMoc(moc: Moc): Model;
/** Updates instance. */
update(): void;
/** Releases instance. */
release(): void;
/** Native model. */
_ptr: number;
/**
* Initializes instance.
*
* @param moc Moc
*/
private constructor();
}
/** Canvas information interface. */
class CanvasInfo {
/** Width of native model canvas. */
CanvasWidth: number;
/** Height of native model canvas. */
CanvasHeight: number;
/** Coordinate origin of X axis. */
CanvasOriginX: number;
/** Coordinate origin of Y axis. */
CanvasOriginY: number;
/** Pixels per unit of native model. */
PixelsPerUnit: number;
/**
* Initializes instance.
*
* @param modelPtr Native model pointer.
*/
constructor(modelPtr: number);
}
/** Cubism model parameters */
class Parameters {
/** Parameter count. */
count: number;
/** Parameter IDs. */
ids: Array<string>;
/** Minimum parameter values. */
minimumValues: Float32Array;
/** Parameter types. */
types: Int32Array;
/** Maximum parameter values. */
maximumValues: Float32Array;
/** Default parameter values. */
defaultValues: Float32Array;
/** Parameter values. */
values: Float32Array;
/** Number of key values of each parameter. */
keyCounts: Int32Array;
/** Key values of each parameter. */
keyValues: Array<Float32Array>;
/**
* Initializes instance.
*
* @param modelPtr Native model.
*/
constructor(modelPtr: number);
}
/** Cubism model parts */
class Parts {
/** Part count. */
count: number;
/** Part IDs. */
ids: Array<string>;
/** Opacity values. */
opacities: Float32Array;
/** Part's parent part indices. */
parentIndices: Int32Array;
/**
* Initializes instance.
*
* @param modelPtr Native model.
*/
constructor(modelPtr: number);
}
/** Cubism model drawables */
class Drawables {
/** Drawable count. */
count: number;
/** Drawable IDs. */
ids: Array<string>;
/** Constant drawable flags. */
constantFlags: Uint8Array;
/** Dynamic drawable flags. */
dynamicFlags: Uint8Array;
/** Drawable texture indices. */
textureIndices: Int32Array;
/** Drawable draw orders. */
drawOrders: Int32Array;
/** Drawable render orders. */
renderOrders: Int32Array;
/** Drawable opacities. */
opacities: Float32Array;
/** Mask count for each drawable. */
maskCounts: Int32Array;
/** Masks for each drawable. */
masks: Array<Int32Array>;
/** Number of vertices of each drawable. */
vertexCounts: Int32Array;
/** 2D vertex position data of each drawable. */
vertexPositions: Array<Float32Array>;
/** 2D texture coordinate data of each drawables. */
vertexUvs: Array<Float32Array>;
/** Number of triangle indices for each drawable. */
indexCounts: Int32Array;
/** Triangle index data for each drawable. */
indices: Array<Uint16Array>;
/** Information multiply color. */
multiplyColors: Float32Array;
/** Information Screen color. */
screenColors: Float32Array;
/** Indices of drawables parent part. */
parentPartIndices: Int32Array;
/** Resets all dynamic drawable flags.. */
resetDynamicFlags(): void;
/** Native model. */
private _modelPtr;
/**
* Initializes instance.
*
* @param modelPtr Native model.
*/
constructor(modelPtr: number);
}
/** Utility functions. */
class Utils {
/**
* Checks whether flag is set in bitfield.
*
* @param bitfield Bitfield to query against.
*
* @return [[true]] if bit set; [[false]] otherwise
*/
static hasBlendAdditiveBit(bitfield: number): boolean;
/**
* Checks whether flag is set in bitfield.
*
* @param bitfield Bitfield to query against.
*
* @return [[true]] if bit set; [[false]] otherwise
*/
static hasBlendMultiplicativeBit(bitfield: number): boolean;
/**
* Checks whether flag is set in bitfield.
*
* @param bitfield Bitfield to query against.
*
* @return [[true]] if bit set; [[false]] otherwise
*/
static hasIsDoubleSidedBit(bitfield: number): boolean;
/**
* Checks whether flag is set in bitfield.
*
* @param bitfield Bitfield to query against.
*
* @return [[true]] if bit set; [[false]] otherwise
*/
static hasIsInvertedMaskBit(bitfield: number): boolean;
/**
* Checks whether flag is set in bitfield.
*
* @param bitfield Bitfield to query against.
*
* @return [[true]] if bit set; [[false]] otherwise
*/
static hasIsVisibleBit(bitfield: number): boolean;
/**
* Checks whether flag is set in bitfield.
*
* @param bitfield Bitfield to query against.
*
* @return [[true]] if bit set; [[false]] otherwise
*/
static hasVisibilityDidChangeBit(bitfield: number): boolean;
/**
* Checks whether flag is set in bitfield.
*
* @param bitfield Bitfield to query against.
*
* @return [[true]] if bit set; [[false]] otherwise
*/
static hasOpacityDidChangeBit(bitfield: number): boolean;
/**
* Checks whether flag is set in bitfield.
*
* @param bitfield Bitfield to query against.
*
* @return [[true]] if bit set; [[false]] otherwise
*/
static hasDrawOrderDidChangeBit(bitfield: number): boolean;
/**
* Checks whether flag is set in bitfield.
*
* @param bitfield Bitfield to query against.
*
* @return [[true]] if bit set; [[false]] otherwise
*/
static hasRenderOrderDidChangeBit(bitfield: number): boolean;
/**
* Checks whether flag is set in bitfield.
*
* @param bitfield Bitfield to query against.
*
* @return [[true]] if bit set; [[false]] otherwise
*/
static hasVertexPositionsDidChangeBit(bitfield: number): boolean;
/**
* Checks whether flag is set in bitfield.
*
* @param bitfield Bitfield to query against.
*
* @return [[true]] if bit set; [[false]] otherwise
*/
static hasBlendColorDidChangeBit(bitfield: number): boolean;
}
/** Memory functions. */
class Memory {
/**
* HACK:
* Extend memory size allocated during module initialization.
* If the specified size is less than or equal to 16777216(byte), the default of 16 MB is allocated.
*
* @see https://github.com/emscripten-core/emscripten/blob/main/src/settings.js#L161
*
* @param size allocated memory size [byte(s)]
*/
static initializeAmountOfMemory(size: number): void;
private constructor();
}
/** Emscripten Cubism Core module. */
}

File diff suppressed because one or more lines are too long

1488
src/deps/live2dcubismcore.min.js vendored Normal file

File diff suppressed because one or more lines are too long

34
src/hooks/useTxt2Voice.ts Normal file
View File

@ -0,0 +1,34 @@
import { useState } from "react";
const synthesizer = typeof window !== 'undefined' && window.speechSynthesis;
const utterance = typeof SpeechSynthesisUtterance != 'undefined' ? new SpeechSynthesisUtterance() : {} as any;
const useTxt2Voice = () => {
const [isSpeaking, setIsSpeaking] = useState(false);
const speak = (text: string) => {
utterance.lang = 'zh-CN';
utterance.rate = 1;
utterance.pitch = 1;
utterance.text = text;
//@ts-ignore
synthesizer.speak(utterance);
}
const stop = () => {
//@ts-ignore
synthesizer.cancel();
}
utterance.onend = () => {
// 语音播放结束后的操作.
setIsSpeaking(false);
}
utterance.onstart = () => {
// 语音播放开始后的操作.
setIsSpeaking(true);
}
return {
isSpeaking,
speak,
stop
}
}
export default useTxt2Voice;

65
src/hooks/useVoice2txt.ts Normal file
View File

@ -0,0 +1,65 @@
import { useEffect, useState } from "react";
type Options = {
lang?: 'cmn-Hans-CN' | 'en-US' | 'ja-JP',
continuous?: boolean,
interimResults?: boolean,
maxAlternatives?: number,
serviceURI?: string,
grammars?: string,
[key: string]: any;
}
type Voice2Txt = {
text: string,
start: () => void,
end: () => void,
isListening: boolean,
error: string | null
}
function useVoice2Txt(options: Options): Voice2Txt {
const [text, setText] = useState("");
const [isListening, setIsListening] = useState(false);
const [error, setError] = useState<string | null>(null);
//@ts-ignore
const recognition = new webkitSpeechRecognition() || new SpeechRecognition();
for (let key in options) {
recognition[key] = options[key];
}
if (typeof recognition === 'undefined') {
setError("浏览器不支持语音识别");
} else {
console.log(recognition);
}
function start() {
if (isListening) return;
setIsListening(true);
recognition.continuous = options.continuous || false;
try {
recognition.start();
} catch (e) {
}
}
function end() {
setIsListening(false);
recognition.stop();
recognition.continuous = false;
}
//@ts-ignore
// 当调用recognition的stop的时候会触发此对象的onresult事件然后我们在这里获取我们的转换结果。
recognition.onresult = function (event) {
setIsListening(false);
setText(event.results[0][0].transcript)
console.log("转换完成", event)
console.log(event.results[0][0].transcript)
}
//@ts-ignore
recognition.onerror = (e) => {
setError(e)
}
return { text, start, end, isListening, error }
}
export default useVoice2Txt;

View File

@ -0,0 +1,14 @@
{
"FileMetadata": {
"LastSavedVTubeStudioVersion": "1.28.1",
"LastSavedPlatform": "Steam",
"LastSavedDateUTC": "Friday, 19 January 2024, 01:15:31",
"LastSavedDateLocalTime": "Friday, 19 January 2024, 09:15:31",
"LastSavedDateUnixMillisecondTimestamp": "1705626931913"
},
"SceneName": "",
"SceneGroupName": "",
"SceneModel": "",
"SceneID": "",
"Items": []
}

View File

@ -0,0 +1,418 @@
{
"Version": 1,
"Name": "yoyo - f",
"ModelID": "577ba17262704283abd49d6a21f5a7df",
"FileReferences": {
"Icon": "",
"Model": "yoyo - f.model3.json",
"IdleAnimation": "",
"IdleAnimationWhenTrackingLost": ""
},
"ModelSaveMetadata": {
"LastSavedVTubeStudioVersion": "1.28.1",
"LastSavedPlatform": "Steam",
"LastSavedDateUTC": "Friday, 19 January 2024, 01:15:33",
"LastSavedDateLocalTime": "Friday, 19 January 2024, 09:15:33",
"LastSavedDateUnixMillisecondTimestamp": "1705626933428"
},
"SavedModelPosition": {
"Position": {
"x": 3.4800148010253908,
"y": -19.799999237060548,
"z": 0.0
},
"Rotation": {
"x": 0.0,
"y": 0.0,
"z": 0.0,
"w": 1.0
},
"Scale": {
"x": 1.5383042097091675,
"y": 1.5383042097091675,
"z": 1.0
}
},
"ModelPositionMovement": {
"Use": true,
"X": 6,
"Y": 8,
"Z": 11,
"SmoothingX": 10,
"SmoothingY": 10,
"SmoothingZ": 10
},
"ItemSettings": {
"OnlyMoveWhenPinned": false,
"AllowNormalHotkeyTriggers": true,
"Multiplier_HeadAngleX": 1.0,
"Multiplier_HeadAngleY": 1.0,
"Multiplier_HeadAngleZ": 1.0,
"Shift_HeadAngleX": 0.0,
"Shift_HeadAngleY": 0.0,
"Smoothing_HeadAngleX": 15.0,
"Smoothing_HeadAngleY": 15.0,
"Smoothing_HeadAngleZ": 15.0
},
"PhysicsSettings": {
"Use": true,
"UseLegacyPhysics": false,
"Live2DPhysicsFPS": 3,
"PhysicsStrength": 50,
"WindStrength": 0,
"DraggingPhysicsStrength": 0
},
"GeneralSettings": {
"TimeUntilTrackingLostIdleAnimation": 0.0,
"WorkshopSharingForbidden": true,
"EnableExpressionSaving": false
},
"ParameterSettings": [
{
"Folder": "",
"Name": "Eye X",
"Input": "EyeRightX",
"InputRangeLower": -1.0,
"InputRangeUpper": 1.0,
"OutputRangeLower": 1.0,
"OutputRangeUpper": -1.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamEyeBallX",
"Smoothing": 8,
"Minimized": false
},
{
"Folder": "",
"Name": "Eye Y",
"Input": "EyeRightY",
"InputRangeLower": -1.0,
"InputRangeUpper": 1.0,
"OutputRangeLower": -1.0,
"OutputRangeUpper": 1.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamEyeBallY",
"Smoothing": 8,
"Minimized": false
},
{
"Folder": "",
"Name": "Eye Open Left",
"Input": "EyeOpenLeft",
"InputRangeLower": 0.0,
"InputRangeUpper": 1.0,
"OutputRangeLower": 0.0,
"OutputRangeUpper": 1.899999976158142,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamEyeLOpen",
"Smoothing": 10,
"Minimized": false
},
{
"Folder": "",
"Name": "Eye Open Right",
"Input": "EyeOpenRight",
"InputRangeLower": 0.0,
"InputRangeUpper": 1.0,
"OutputRangeLower": 0.0,
"OutputRangeUpper": 1.899999976158142,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamEyeROpen",
"Smoothing": 10,
"Minimized": false
},
{
"Folder": "",
"Name": "Mouth Smile",
"Input": "MouthSmile",
"InputRangeLower": 0.0,
"InputRangeUpper": 1.0,
"OutputRangeLower": -1.0,
"OutputRangeUpper": 1.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamMouthForm",
"Smoothing": 0,
"Minimized": false
},
{
"Folder": "",
"Name": "Mouth Open",
"Input": "MouthOpen",
"InputRangeLower": 0.0,
"InputRangeUpper": 1.0,
"OutputRangeLower": 0.0,
"OutputRangeUpper": 2.0999999046325685,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamMouthOpenY",
"Smoothing": 0,
"Minimized": false
},
{
"Folder": "",
"Name": "Body Rotation X",
"Input": "FaceAngleX",
"InputRangeLower": -30.0,
"InputRangeUpper": 30.0,
"OutputRangeLower": -10.0,
"OutputRangeUpper": 10.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamBodyAngleX",
"Smoothing": 20,
"Minimized": false
},
{
"Folder": "",
"Name": "Body Rotation Y",
"Input": "FaceAngleY",
"InputRangeLower": -30.0,
"InputRangeUpper": 30.0,
"OutputRangeLower": -10.0,
"OutputRangeUpper": 10.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamBodyAngleY",
"Smoothing": 20,
"Minimized": false
},
{
"Folder": "",
"Name": "Body Rotation Z",
"Input": "FaceAngleZ",
"InputRangeLower": -30.0,
"InputRangeUpper": 30.0,
"OutputRangeLower": -10.0,
"OutputRangeUpper": 10.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamBodyAngleZ",
"Smoothing": 20,
"Minimized": false
},
{
"Folder": "",
"Name": "Face Left/Right Rotation",
"Input": "FaceAngleX",
"InputRangeLower": -30.0,
"InputRangeUpper": 30.0,
"OutputRangeLower": -30.0,
"OutputRangeUpper": 30.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamAngleX",
"Smoothing": 15,
"Minimized": false
},
{
"Folder": "",
"Name": "Face Up/Down Rotation",
"Input": "FaceAngleY",
"InputRangeLower": -20.0,
"InputRangeUpper": 20.0,
"OutputRangeLower": -30.0,
"OutputRangeUpper": 30.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamAngleY",
"Smoothing": 15,
"Minimized": false
},
{
"Folder": "",
"Name": "Face Lean Rotation",
"Input": "FaceAngleZ",
"InputRangeLower": -30.0,
"InputRangeUpper": 30.0,
"OutputRangeLower": -30.0,
"OutputRangeUpper": 30.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamAngleZ",
"Smoothing": 30,
"Minimized": false
},
{
"Folder": "",
"Name": "Eye Smile Left",
"Input": "MouthSmile",
"InputRangeLower": 0.0,
"InputRangeUpper": 1.0,
"OutputRangeLower": 0.0,
"OutputRangeUpper": 1.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamEyeLSmile",
"Smoothing": 10,
"Minimized": false
},
{
"Folder": "",
"Name": "Eye Smile Right",
"Input": "MouthSmile",
"InputRangeLower": 0.0,
"InputRangeUpper": 1.0,
"OutputRangeLower": 0.0,
"OutputRangeUpper": 1.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamEyeRSmile",
"Smoothing": 10,
"Minimized": false
},
{
"Folder": "",
"Name": "Brow Height Left",
"Input": "Brows",
"InputRangeLower": 0.0,
"InputRangeUpper": 1.0,
"OutputRangeLower": -1.0,
"OutputRangeUpper": 1.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamBrowLY",
"Smoothing": 10,
"Minimized": false
},
{
"Folder": "",
"Name": "Brow Height Right",
"Input": "Brows",
"InputRangeLower": 0.0,
"InputRangeUpper": 1.0,
"OutputRangeLower": -1.0,
"OutputRangeUpper": 1.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamBrowRY",
"Smoothing": 10,
"Minimized": false
},
{
"Folder": "",
"Name": "Brow Form Left",
"Input": "Brows",
"InputRangeLower": 0.0,
"InputRangeUpper": 1.0,
"OutputRangeLower": -1.0,
"OutputRangeUpper": 1.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamBrowLForm",
"Smoothing": 15,
"Minimized": false
},
{
"Folder": "",
"Name": "Brow Form Right",
"Input": "Brows",
"InputRangeLower": 0.0,
"InputRangeUpper": 1.0,
"OutputRangeLower": -1.0,
"OutputRangeUpper": 1.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamBrowRForm",
"Smoothing": 15,
"Minimized": false
},
{
"Folder": "",
"Name": "Blush when smiling",
"Input": "MouthSmile",
"InputRangeLower": 0.0,
"InputRangeUpper": 1.0,
"OutputRangeLower": 0.5,
"OutputRangeUpper": 1.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": false,
"OutputLive2D": "ParamCheek",
"Smoothing": 45,
"Minimized": false
},
{
"Folder": "",
"Name": "Auto Breath",
"Input": "",
"InputRangeLower": 0.0,
"InputRangeUpper": 1.0,
"OutputRangeLower": 0.0,
"OutputRangeUpper": 1.0,
"ClampInput": false,
"ClampOutput": false,
"UseBlinking": false,
"UseBreathing": true,
"OutputLive2D": "ParamBreath",
"Smoothing": 0,
"Minimized": false
}
],
"Hotkeys": [],
"HotkeySettings": {
"UseOnScreenHotkeys": false,
"UseKeyboardHotkeys": true,
"SendOnScreenHotkeysToPC": true,
"OnScreenHotkeyAlpha": 75
},
"ArtMeshDetails": {
"ArtMeshesExcludedFromPinning": [],
"ArtMeshesThatDeleteItemsOnDrop": [],
"ArtMeshSceneLightingMultipliers": [],
"ArtMeshMultiplyAndScreenColors": []
},
"ParameterCustomization": {
"ParametersExcludedFromVNetSmoothing": []
},
"PhysicsCustomizationSettings": {
"PhysicsMultipliersPerPhysicsGroup": [],
"WindMultipliersPerPhysicsGroup": [],
"DraggingPhysicsMultipliersPerPhysicsGroup": []
},
"FolderInfo": {
"HotkeyFolders": [],
"ConfigItemFolders": []
},
"SavedActiveExpressions": []
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 MiB

View File

@ -0,0 +1,644 @@
{
"Version": 3,
"Parameters": [
{
"Id": "ParamEyeBallX",
"GroupId": "ParamGroup",
"Name": "眼珠 X"
},
{
"Id": "ParamEyeBallY",
"GroupId": "ParamGroup",
"Name": "眼珠 Y"
},
{
"Id": "ParamEyeLOpen",
"GroupId": "ParamGroup",
"Name": "左眼 开闭"
},
{
"Id": "ParamEyeROpen",
"GroupId": "ParamGroup",
"Name": "右眼"
},
{
"Id": "ParamMouthForm",
"GroupId": "ParamGroup2",
"Name": "嘴 变形"
},
{
"Id": "ParamMouthOpenY",
"GroupId": "ParamGroup2",
"Name": "嘴 张开和闭合"
},
{
"Id": "Param59",
"GroupId": "ParamGroup2",
"Name": "鼓嘴"
},
{
"Id": "Param60",
"GroupId": "ParamGroup2",
"Name": "歪嘴"
},
{
"Id": "Param61",
"GroupId": "ParamGroup2",
"Name": "咀嚼"
},
{
"Id": "ParamBodyAngleX",
"GroupId": "ParamGroup7",
"Name": "身体旋转 X"
},
{
"Id": "ParamBodyAngleY",
"GroupId": "ParamGroup7",
"Name": "身体旋转 Y"
},
{
"Id": "ParamBodyAngleZ",
"GroupId": "ParamGroup7",
"Name": "身体旋转 Z"
},
{
"Id": "ParamAngleX",
"GroupId": "ParamGroup7",
"Name": "角度 X"
},
{
"Id": "ParamAngleY",
"GroupId": "ParamGroup7",
"Name": "角度 Y"
},
{
"Id": "ParamAngleZ",
"GroupId": "ParamGroup7",
"Name": "角度 Z"
},
{
"Id": "Param",
"GroupId": "ParamGroup3",
"Name": "眼睛R"
},
{
"Id": "Param2",
"GroupId": "ParamGroup3",
"Name": "眼睛R2"
},
{
"Id": "Param4",
"GroupId": "ParamGroup3",
"Name": "瞳孔R"
},
{
"Id": "Param5",
"GroupId": "ParamGroup3",
"Name": "高光X"
},
{
"Id": "Param6",
"GroupId": "ParamGroup3",
"Name": "高光Y"
},
{
"Id": "Param7",
"GroupId": "ParamGroup3",
"Name": "高光Z"
},
{
"Id": "Param8",
"GroupId": "ParamGroup3",
"Name": "高光Z2"
},
{
"Id": "Param9",
"GroupId": "ParamGroup3",
"Name": "眼框Y"
},
{
"Id": "Param10",
"GroupId": "ParamGroup3",
"Name": "睫毛"
},
{
"Id": "Param3",
"GroupId": "ParamGroup4",
"Name": "眼睛L"
},
{
"Id": "Param11",
"GroupId": "ParamGroup4",
"Name": "眼睛L2"
},
{
"Id": "Param12",
"GroupId": "ParamGroup4",
"Name": "瞳孔L"
},
{
"Id": "Param13",
"GroupId": "ParamGroup4",
"Name": "高光XL"
},
{
"Id": "Param14",
"GroupId": "ParamGroup4",
"Name": "高光YL"
},
{
"Id": "Param15",
"GroupId": "ParamGroup4",
"Name": "高光ZL"
},
{
"Id": "Param16",
"GroupId": "ParamGroup4",
"Name": "高光Z2L"
},
{
"Id": "Param17",
"GroupId": "ParamGroup4",
"Name": "眼框YL"
},
{
"Id": "Param18",
"GroupId": "ParamGroup4",
"Name": "睫毛L"
},
{
"Id": "Param19",
"GroupId": "ParamGroup5",
"Name": "耳朵1"
},
{
"Id": "Param20",
"GroupId": "ParamGroup5",
"Name": "耳朵2"
},
{
"Id": "Param21",
"GroupId": "ParamGroup5",
"Name": "耳朵3"
},
{
"Id": "Param22",
"GroupId": "ParamGroup5",
"Name": "耳朵4"
},
{
"Id": "Param35",
"GroupId": "ParamGroup5",
"Name": "耳环"
},
{
"Id": "Param23",
"GroupId": "ParamGroup6",
"Name": "耳朵1"
},
{
"Id": "Param24",
"GroupId": "ParamGroup6",
"Name": "耳朵2"
},
{
"Id": "Param25",
"GroupId": "ParamGroup6",
"Name": "耳朵3"
},
{
"Id": "Param26",
"GroupId": "ParamGroup6",
"Name": "耳朵4"
},
{
"Id": "Param36",
"GroupId": "ParamGroup6",
"Name": "耳环"
},
{
"Id": "Param27",
"GroupId": "ParamGroup8",
"Name": "刘海"
},
{
"Id": "Param28",
"GroupId": "ParamGroup8",
"Name": "刘海XX"
},
{
"Id": "Param31",
"GroupId": "ParamGroup8",
"Name": "刘海Y"
},
{
"Id": "Param32",
"GroupId": "ParamGroup8",
"Name": "刘海YY"
},
{
"Id": "Param29",
"GroupId": "ParamGroup8",
"Name": "辫子X"
},
{
"Id": "Param30",
"GroupId": "ParamGroup8",
"Name": "辫子XX"
},
{
"Id": "Param33",
"GroupId": "ParamGroup8",
"Name": "辫子Y"
},
{
"Id": "Param34",
"GroupId": "ParamGroup8",
"Name": "辫子YY"
},
{
"Id": "Param37",
"GroupId": "ParamGroup9",
"Name": "手臂"
},
{
"Id": "Param38",
"GroupId": "ParamGroup9",
"Name": "手臂X"
},
{
"Id": "Param39",
"GroupId": "ParamGroup9",
"Name": "手臂"
},
{
"Id": "Param40",
"GroupId": "ParamGroup9",
"Name": "手臂X"
},
{
"Id": "Param41",
"GroupId": "ParamGroup10",
"Name": "裙ZX"
},
{
"Id": "Param42",
"GroupId": "ParamGroup10",
"Name": "裙ZXX"
},
{
"Id": "Param43",
"GroupId": "ParamGroup10",
"Name": "裙ZY"
},
{
"Id": "Param44",
"GroupId": "ParamGroup10",
"Name": "裙ZYY"
},
{
"Id": "Param46",
"GroupId": "ParamGroup12",
"Name": "尾巴X"
},
{
"Id": "Param47",
"GroupId": "ParamGroup12",
"Name": "尾巴XX"
},
{
"Id": "ParamEyeLSmile",
"GroupId": "",
"Name": "左眼 微笑"
},
{
"Id": "ParamEyeRSmile",
"GroupId": "",
"Name": "右眼 微笑"
},
{
"Id": "ParamBrowLY",
"GroupId": "",
"Name": "左眉上下"
},
{
"Id": "ParamBrowRY",
"GroupId": "",
"Name": "右眉 上下"
},
{
"Id": "ParamBrowLX",
"GroupId": "",
"Name": "左眉 左右"
},
{
"Id": "ParamBrowRX",
"GroupId": "",
"Name": "右眉 左右"
},
{
"Id": "ParamBrowLAngle",
"GroupId": "",
"Name": "左眉 角度"
},
{
"Id": "ParamBrowRAngle",
"GroupId": "",
"Name": "右眉 角度"
},
{
"Id": "ParamBrowLForm",
"GroupId": "",
"Name": "左眉 変形"
},
{
"Id": "ParamBrowRForm",
"GroupId": "",
"Name": "右眉 変形"
},
{
"Id": "ParamCheek",
"GroupId": "",
"Name": "脸颊泛红"
},
{
"Id": "ParamBreath",
"GroupId": "",
"Name": "呼吸"
},
{
"Id": "ParamHairFront",
"GroupId": "",
"Name": "摇动 前发"
},
{
"Id": "ParamHairSide",
"GroupId": "",
"Name": "摇动 侧发"
},
{
"Id": "ParamHairBack",
"GroupId": "",
"Name": "摇动 后发"
},
{
"Id": "Param_Angle_Rotation_1_ArtMesh123",
"GroupId": "ParamGroup13",
"Name": "[0]尾巴"
},
{
"Id": "Param_Angle_Rotation_2_ArtMesh123",
"GroupId": "ParamGroup13",
"Name": "[1]尾巴"
},
{
"Id": "Param_Angle_Rotation_3_ArtMesh123",
"GroupId": "ParamGroup13",
"Name": "[2]尾巴"
},
{
"Id": "Param_Angle_Rotation_4_ArtMesh123",
"GroupId": "ParamGroup13",
"Name": "[3]尾巴"
},
{
"Id": "Param_Angle_Rotation_5_ArtMesh123",
"GroupId": "ParamGroup13",
"Name": "[4]尾巴"
}
],
"ParameterGroups": [
{
"Id": "ParamGroup",
"GroupId": "",
"Name": "眼睛"
},
{
"Id": "ParamGroup2",
"GroupId": "",
"Name": "嘴"
},
{
"Id": "ParamGroup7",
"GroupId": "",
"Name": "九轴"
},
{
"Id": "ParamGroup3",
"GroupId": "",
"Name": "果冻"
},
{
"Id": "ParamGroup4",
"GroupId": "",
"Name": "果冻"
},
{
"Id": "ParamGroup5",
"GroupId": "",
"Name": "耳朵"
},
{
"Id": "ParamGroup6",
"GroupId": "",
"Name": "耳朵L"
},
{
"Id": "ParamGroup8",
"GroupId": "",
"Name": "头发物理"
},
{
"Id": "ParamGroup9",
"GroupId": "",
"Name": "手臂"
},
{
"Id": "ParamGroup10",
"GroupId": "",
"Name": "裙子"
},
{
"Id": "ParamGroup12",
"GroupId": "",
"Name": "尾巴"
},
{
"Id": "ParamGroup13",
"GroupId": "",
"Name": "尾巴"
}
],
"Parts": [
{
"Id": "Part36",
"Name": "试用中.png"
},
{
"Id": "Part34",
"Name": "未标题-1.psd"
},
{
"Id": "Part31",
"Name": "+.psd"
},
{
"Id": "Part",
"Name": "表情"
},
{
"Id": "Part7",
"Name": "装饰"
},
{
"Id": "Part9",
"Name": "前发"
},
{
"Id": "Part16",
"Name": "眼泪"
},
{
"Id": "Part14",
"Name": "脸"
},
{
"Id": "Part23",
"Name": "身体衣服"
},
{
"Id": "Part27",
"Name": "腿"
},
{
"Id": "Part28",
"Name": "手臂R"
},
{
"Id": "Part29",
"Name": "手臂L"
},
{
"Id": "Part30",
"Name": "后发"
},
{
"Id": "ArtMesh123_Skinning",
"Name": "尾巴(蒙皮)"
},
{
"Id": "Part33",
"Name": "尾巴(旋转)"
},
{
"Id": "Part2",
"Name": "抱着毛毛"
},
{
"Id": "Part3",
"Name": "爱心"
},
{
"Id": "Part4",
"Name": "疑问流汗"
},
{
"Id": "Part5",
"Name": "唉"
},
{
"Id": "Part6",
"Name": "啊"
},
{
"Id": "ok",
"Name": "ok"
},
{
"Id": "Part8",
"Name": "头饰小猫"
},
{
"Id": "Part10",
"Name": "耳朵L"
},
{
"Id": "Part11",
"Name": "耳朵R"
},
{
"Id": "Part12",
"Name": "辫子R"
},
{
"Id": "Part13",
"Name": "辫子L"
},
{
"Id": "Part17",
"Name": "眼L"
},
{
"Id": "Part15",
"Name": "眼R"
},
{
"Id": "Part19",
"Name": "脸基"
},
{
"Id": "Part22",
"Name": "耳朵"
},
{
"Id": "Part24",
"Name": "领子"
},
{
"Id": "Part25",
"Name": "口子"
},
{
"Id": "Part26",
"Name": "身体"
},
{
"Id": "Part32",
"Name": "耳朵R"
},
{
"Id": "Part18",
"Name": "眼睛的东西 副本"
},
{
"Id": "Part35",
"Name": "眼睛的东西 副本"
},
{
"Id": "Part20",
"Name": "嘴巴"
},
{
"Id": "Part21",
"Name": "舔嘴"
}
],
"CombinedParameters": [
[
"ParamEyeBallX",
"ParamEyeBallY"
],
[
"ParamBodyAngleX",
"ParamBodyAngleY"
],
[
"ParamAngleX",
"ParamAngleY"
],
[
"Param33",
"Param34"
]
]
}

Binary file not shown.

View File

@ -0,0 +1,21 @@
{
"Version": 3,
"FileReferences": {
"Moc": "yoyo.moc3",
"Textures": ["yoyo.16384/texture_00.png"],
"Physics": "yoyo.physics3.json",
"DisplayInfo": "yoyo.cdi3.json"
},
"Groups": [
{
"Target": "Parameter",
"Name": "LipSync",
"Ids": []
},
{
"Target": "Parameter",
"Name": "EyeBlink",
"Ids": []
}
]
}

File diff suppressed because it is too large Load Diff

1631
yarn.lock Normal file

File diff suppressed because it is too large Load Diff