update
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
*/*-lock.json
|
||||||
|
*/node_modules
|
||||||
|
*.sqlite
|
||||||
|
*.lock
|
||||||
|
*target
|
52
docker/PixelStreamingInfrastructure/Public/player.html
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html style="width: 100%; height: 100%">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<!-- Optional: apply a font -->
|
||||||
|
<!--
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Michroma&family=Montserrat:wght@600&display=swap" rel="stylesheet">
|
||||||
|
-->
|
||||||
|
<!-- Optional: set some favicons -->
|
||||||
|
<link rel="shortcut icon" href="43ef81525e6853dc.ico" type="image/x-icon">
|
||||||
|
<link rel="icon" type="image/png" sizes="96x96" href="images/favicon-96x96.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="images/favicon-32x32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="images/favicon-16x16.png">
|
||||||
|
|
||||||
|
<!-- Optional: set a title for your page -->
|
||||||
|
<title>Pixel Streaming</title>
|
||||||
|
<script defer src="player.js"></script></head>
|
||||||
|
|
||||||
|
<!-- The Pixel Streaming player fills 100% of its parent element but body has a 0px height unless filled with content. As such, we explicitly force the body to be 100% of the viewport height -->
|
||||||
|
<body style="width: 100vw; height: 100vh; min-height: -webkit-fill-available; font-family: 'Montserrat'; margin: 0px">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
button#settingsBtn {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
button#statsBtn {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
button#fullscreen-btn {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
div#connection{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.comment {
|
||||||
|
text-align: right;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
a{
|
||||||
|
text-decoration: none;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="comment">
|
||||||
|
<a href="https://bsky.app/profile/yui.syui.ai/feed/cmd">/comment</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
7
docker/python-oauth-web-app/Dockerfile
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
FROM syui/aios
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . .
|
||||||
|
RUN pacman -Syu rye --noconfirm
|
||||||
|
RUN rye sync
|
||||||
|
#CMD ["rye", "run", "flask", "run"]
|
10
docker/python-oauth-web-app/compose.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
services:
|
||||||
|
web:
|
||||||
|
build: .
|
||||||
|
env_file:
|
||||||
|
- ./.env
|
||||||
|
ports:
|
||||||
|
- "5000:5000"
|
||||||
|
volumes:
|
||||||
|
- ./demo.sqlite:/app/demo.sqlite
|
||||||
|
command: rye run flask run
|
40
docker/python-oauth-web-app/templates/base.html
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="referrer" content="origin-when-cross-origin">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.classless.purple.min.css">
|
||||||
|
<title>atproto OAuth Web Service Example</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<hgroup>
|
||||||
|
{% if g.user %}
|
||||||
|
{% endif %}
|
||||||
|
</hgroup>
|
||||||
|
<nav>
|
||||||
|
<ul>
|
||||||
|
{% if g.user %}
|
||||||
|
<li><a href="{{ url_for('bsky_post') }}">Create Post</a>
|
||||||
|
<li><a href="{{ url_for('oauth_refresh') }}">Refresh Token</a>
|
||||||
|
<li><a href="{{ url_for('oauth_logout') }}">Logout</a>
|
||||||
|
{% else %}
|
||||||
|
<li><a href="{{ url_for('oauth_login') }}">Login</a>
|
||||||
|
{% endif %}
|
||||||
|
<!--
|
||||||
|
<li><a href="https://github.com/bluesky-social/cookbook">Code</a>
|
||||||
|
-->
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<section class="content">
|
||||||
|
{% for message in get_flashed_messages() %}
|
||||||
|
<article>{{ message }}</article>
|
||||||
|
{% endfor %}
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
15
docker/python-oauth-web-app/templates/home.html
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{% extends 'base.html' %}
|
||||||
|
{% block content %}
|
||||||
|
{% if g.user %}
|
||||||
|
<div class="livestream">
|
||||||
|
<iframe id="livestream" title="stream" width="100%" height="700px" src="https://live.syui.ai/b9ec42d4-8a4d-4343-99fc-1bd1cdbc5a6f.html"> </iframe>
|
||||||
|
</div>
|
||||||
|
@<span class="user-handle">{{ g.user['handle'] }}</span>
|
||||||
|
<div class="livechat">
|
||||||
|
<iframe id="livechat" title="bskychat" width="100%" height="500" src="https://bbs.syui.ai/?handle={{ session['user_handle'] }}"> </iframe>
|
||||||
|
</div>
|
||||||
|
<style> /* .livechat { position: absolute; top: 0px; right:0px; } */ </style>
|
||||||
|
{% else %}
|
||||||
|
<p>Login to get started!</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
13
docker/restreamer/compose.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
services:
|
||||||
|
|
||||||
|
restreamer:
|
||||||
|
image: datarhei/restreamer
|
||||||
|
#image: datarhei/restreamer:cuda-latest
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
|
- 1935:1935
|
||||||
|
- 6000:6000/udp
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./data/config:/core/config
|
||||||
|
- ./data/data:/core/data
|
11
docker/rust-bbs/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "rust-bbs"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
actix-web = "4.0"
|
||||||
|
url = "2.3.1"
|
||||||
|
rusqlite = { version = "0.28", features = ["bundled"] }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
askama = "*"
|
7
docker/rust-bbs/Dockerfile
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
FROM syui/aios
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY . .
|
||||||
|
RUN cargo build --release
|
||||||
|
COPY ./templates /templates
|
||||||
|
CMD ["/app/target/release/rust-bbs"]
|
7
docker/rust-bbs/compose.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
services:
|
||||||
|
web:
|
||||||
|
build: .
|
||||||
|
ports:
|
||||||
|
- "8782:8782"
|
||||||
|
volumes:
|
||||||
|
- ./sqlite.db:/app/sqlite.db
|
127
docker/rust-bbs/src/main.rs
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
use askama::Template;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use rusqlite::{Connection, Result as SqliteResult};
|
||||||
|
use actix_web::{web, App, HttpServer, HttpResponse, Responder, HttpRequest, Error};
|
||||||
|
use actix_web::error::{ErrorInternalServerError};
|
||||||
|
|
||||||
|
use std::fmt;
|
||||||
|
impl fmt::Display for Post {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "@{} {}", self.handle.as_deref().unwrap_or("anonymous"), self.content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Default)]
|
||||||
|
struct QueryParams {
|
||||||
|
handle: Option<String>,
|
||||||
|
}
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
struct Post {
|
||||||
|
id: i32,
|
||||||
|
handle: Option<String>,
|
||||||
|
content: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(path = "index.html")]
|
||||||
|
struct IndexTemplate {
|
||||||
|
posts: Vec<Post>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(path = "post.html")]
|
||||||
|
struct PostTemplate {}
|
||||||
|
|
||||||
|
fn init_db() -> SqliteResult<()> {
|
||||||
|
let conn = Connection::open("sqlite.db")?;
|
||||||
|
conn.execute(
|
||||||
|
"CREATE TABLE IF NOT EXISTS posts (
|
||||||
|
id INTEGER PRIMARY KEY,
|
||||||
|
handle TEXT NOT NULL,
|
||||||
|
content TEXT NOT NULL
|
||||||
|
)",
|
||||||
|
[],
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn index() -> impl Responder {
|
||||||
|
let conn = Connection::open("sqlite.db").unwrap();
|
||||||
|
let mut stmt = conn.prepare("SELECT id, handle, content FROM posts ORDER BY id DESC").unwrap();
|
||||||
|
let posts = stmt.query_map([], |row| {
|
||||||
|
Ok(Post {
|
||||||
|
id: row.get(0)?,
|
||||||
|
handle: row.get(1)?,
|
||||||
|
content: row.get(2)?,
|
||||||
|
})
|
||||||
|
}).unwrap().filter_map(Result::ok).collect::<Vec<Post>>();
|
||||||
|
|
||||||
|
let template = IndexTemplate { posts };
|
||||||
|
HttpResponse::Ok().body(template.render().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn post_form() -> impl Responder {
|
||||||
|
let template = PostTemplate {};
|
||||||
|
HttpResponse::Ok().body(template.render().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct FormData {
|
||||||
|
handle: String,
|
||||||
|
content: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn submit_post(
|
||||||
|
req: HttpRequest,
|
||||||
|
form: web::Form<FormData>
|
||||||
|
) -> Result<impl Responder, Error> {
|
||||||
|
let query = web::Query::<QueryParams>::from_query(req.query_string())
|
||||||
|
.unwrap_or_else(|_| web::Query(QueryParams { handle: None }));
|
||||||
|
//let handle = query.handle.clone().filter(|h| !h.is_empty());
|
||||||
|
//println!("Debug: Extracted handle: {:?}", handle);
|
||||||
|
let handle = if !form.handle.is_empty() {
|
||||||
|
form.handle.clone()
|
||||||
|
} else {
|
||||||
|
query.handle.clone().unwrap_or_default()
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("Debug: Using handle: {:?}", handle);
|
||||||
|
|
||||||
|
let conn = Connection::open("sqlite.db")
|
||||||
|
.map_err(|_| ErrorInternalServerError("Database connection failed"))?;
|
||||||
|
let result = conn.execute(
|
||||||
|
"INSERT INTO posts (handle, content) VALUES (?1, ?2)",
|
||||||
|
&[&form.handle, &form.content],
|
||||||
|
);
|
||||||
|
match result {
|
||||||
|
Ok(_) => {
|
||||||
|
let redirect_url = if !handle.is_empty() {
|
||||||
|
format!("/?handle={}", handle)
|
||||||
|
} else {
|
||||||
|
"/".to_string()
|
||||||
|
};
|
||||||
|
Ok(HttpResponse::SeeOther()
|
||||||
|
.append_header(("Location",
|
||||||
|
redirect_url))
|
||||||
|
.finish())
|
||||||
|
},
|
||||||
|
|
||||||
|
//Ok(_) => Ok(web::Redirect::to("/").see_other()),
|
||||||
|
Err(_) => Err(ErrorInternalServerError("Failed to insert post")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[actix_web::main]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
init_db().unwrap();
|
||||||
|
|
||||||
|
HttpServer::new(|| {
|
||||||
|
App::new()
|
||||||
|
.route("/", web::get().to(index))
|
||||||
|
.route("/post", web::get().to(post_form))
|
||||||
|
.route("/submit", web::post().to(submit_post))
|
||||||
|
})
|
||||||
|
.bind("0.0.0.0:8782")?
|
||||||
|
.run()
|
||||||
|
.await
|
||||||
|
}
|
67
docker/rust-bbs/templates/index.html
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Simple BBS</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ul>
|
||||||
|
{% for post in posts %}
|
||||||
|
<li><span class="user-post">{{ post }}</span></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
<form action="/submit" method="post">
|
||||||
|
<input type="hidden" name="handle" id="handleInput">
|
||||||
|
<textarea name="content" required></textarea>
|
||||||
|
<input type="submit" value="Post">
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function getHandleFromUrl() {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
return urlParams.get('handle');
|
||||||
|
}
|
||||||
|
window.onload = function() {
|
||||||
|
const handle = getHandleFromUrl();
|
||||||
|
if (handle) {
|
||||||
|
document.getElementById('handleInput').value = handle;
|
||||||
|
} else {
|
||||||
|
document.getElementById('handleInput').value = "anonymous";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
li {
|
||||||
|
width: 100%;
|
||||||
|
list-style: none;
|
||||||
|
padding: 10px 0px;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
textarea {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 5px;
|
||||||
|
resize: none;
|
||||||
|
border-bottom: 3px solid #2e7b96;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
input[type="submit"] {
|
||||||
|
border-radius: 5px;
|
||||||
|
width: 100%;
|
||||||
|
color: #fff;
|
||||||
|
background: #bb1a1a;
|
||||||
|
border: none;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0 auto;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
span.user-post {
|
||||||
|
padding: 0px 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</html>
|
14
docker/rust-bbs/templates/post.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>New Post</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>New Post</h1>
|
||||||
|
<form action="/submit" method="post">
|
||||||
|
<textarea name="content" required></textarea>
|
||||||
|
<br>
|
||||||
|
<input type="submit" value="Post">
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
BIN
issue/screenshots/issue-9-0001.png
Executable file
After Width: | Height: | Size: 174 KiB |
BIN
issue/screenshots/issue-9-0002.png
Executable file
After Width: | Height: | Size: 93 KiB |
BIN
issue/screenshots/issue-9-0003.png
Executable file
After Width: | Height: | Size: 792 KiB |
BIN
issue/screenshots/issue-9-0004.png
Executable file
After Width: | Height: | Size: 64 KiB |
56
plugins/vmc4ue/VMC4UEBlueprintFunctionLibrary.cpp.patch
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
--- ./VMC4UE/VMC4UE/Source/VMC4UE/Source/VMC4UEBlueprintFunctionLibrary.cpp
|
||||||
|
+++ ./VMC4UEBlueprintFunctionLibrary.cpp
|
||||||
|
@@ -119,27 +119,29 @@ UVMC4UEStreamingSkeletalMeshTransform* UVMC4UEBlueprin
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
+
|
||||||
|
+ UVMC4UEStreamingSkeletalMeshTransform* StreamingSkeletalMeshTransform = nullptr;
|
||||||
|
+
|
||||||
|
+ // Try to get existing transform
|
||||||
|
{
|
||||||
|
- // Get
|
||||||
|
FRWScopeLock RWScopeLock(OSCManager->RWLock, FRWScopeLockType::SLT_ReadOnly);
|
||||||
|
- auto StreamingSkeletalMeshTransform = OSCManager->StreamingSkeletalMeshTransformMap.Find(Port);
|
||||||
|
- if (StreamingSkeletalMeshTransform != nullptr)
|
||||||
|
+ auto FoundTransform = OSCManager->StreamingSkeletalMeshTransformMap.Find(Port);
|
||||||
|
+ if (FoundTransform != nullptr)
|
||||||
|
{
|
||||||
|
- return *StreamingSkeletalMeshTransform;
|
||||||
|
+ return *FoundTransform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ // Create new transform if not found
|
||||||
|
{
|
||||||
|
- // Create
|
||||||
|
FRWScopeLock RWScopeLock(OSCManager->RWLock, FRWScopeLockType::SLT_Write);
|
||||||
|
- auto StreamingSkeletalMeshTransform = OSCManager->StreamingSkeletalMeshTransformMap.Find(Port);
|
||||||
|
- if (StreamingSkeletalMeshTransform != nullptr)
|
||||||
|
+ auto FoundTransform = OSCManager->StreamingSkeletalMeshTransformMap.Find(Port);
|
||||||
|
+ if (FoundTransform != nullptr)
|
||||||
|
{
|
||||||
|
- return *StreamingSkeletalMeshTransform;
|
||||||
|
+ return *FoundTransform;
|
||||||
|
}
|
||||||
|
- UVMC4UEStreamingSkeletalMeshTransform* NewStreamingSkeletalMeshTransform = NewObject<UVMC4UEStreamingSkeletalMeshTransform>();
|
||||||
|
|
||||||
|
- //FRWScopeLock RWScopeLock2(NewStreamingSkeletalMeshTransform->RWLock, FRWScopeLockType::SLT_Write);
|
||||||
|
+ UVMC4UEStreamingSkeletalMeshTransform* NewStreamingSkeletalMeshTransform = NewObject<UVMC4UEStreamingSkeletalMeshTransform>();
|
||||||
|
OSCManager->StreamingSkeletalMeshTransformMap.Emplace(Port, NewStreamingSkeletalMeshTransform);
|
||||||
|
|
||||||
|
// Bind Port
|
||||||
|
@@ -149,9 +151,10 @@ UVMC4UEStreamingSkeletalMeshTransform* UVMC4UEBlueprin
|
||||||
|
|
||||||
|
OSCManager->OscReceivers.Emplace(OscReceiver);
|
||||||
|
|
||||||
|
- return NewStreamingSkeletalMeshTransform;
|
||||||
|
+ StreamingSkeletalMeshTransform = NewStreamingSkeletalMeshTransform;
|
||||||
|
}
|
||||||
|
- return nullptr;
|
||||||
|
+
|
||||||
|
+ return StreamingSkeletalMeshTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UVMC4UEBlueprintFunctionLibrary::RefreshConnection(float Seconds)
|
25
plugins/vmc4ue/VMC4UEBoneMappingAssetFactory.cpp.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
--- ./VMC4UE/Source/VMC4UEEd/Source/VMC4UEBoneMappingAssetFactory.cpp
|
||||||
|
+++ ./VMC4UEBoneMappingAssetFactory.cpp
|
||||||
|
@@ -5,6 +5,8 @@
|
||||||
|
#include "../../VMC4UE/Include/VMC4UEStreamingData.h"
|
||||||
|
#include "Dom/JsonObject.h"
|
||||||
|
#include "JsonObjectConverter.h"
|
||||||
|
+#include "UObject/ConstructorHelpers.h"
|
||||||
|
+#include "UObject/UObjectGlobals.h"
|
||||||
|
|
||||||
|
UVMC4UEBoneMappingAssetFactory::UVMC4UEBoneMappingAssetFactory(const FObjectInitializer &ObjectInitializer)
|
||||||
|
: Super(ObjectInitializer)
|
||||||
|
@@ -26,11 +28,12 @@
|
||||||
|
return UVMC4UEVRMMapping::StaticClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
+
|
||||||
|
UObject *UVMC4UEBoneMappingAssetFactory::FactoryCreateText(UClass *InClass, UObject *InParent, FName InName, EObjectFlags Flags, UObject *Context, const TCHAR *Type, const TCHAR *&Buffer, const TCHAR *BuferEnd, FFeedbackContext *Warn)
|
||||||
|
{
|
||||||
|
FString TextData = FString(Buffer);
|
||||||
|
|
||||||
|
- UVMC4UEVRMMapping *NewAsset = CastChecked<UVMC4UEVRMMapping>(StaticConstructObject_Internal(InClass, InParent, InName, Flags));
|
||||||
|
+ UVMC4UEVRMMapping* NewAsset = NewObject<UVMC4UEVRMMapping>(InParent, InClass, InName, Flags);
|
||||||
|
if (!IsValid(NewAsset))
|
||||||
|
{
|
||||||
|
return nullptr;
|
23
plugins/vmc4ue/readme.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
vmc4ue patch rebuild for `ue5.4`
|
||||||
|
|
||||||
|
- https://github.com/HAL9HARUKU/VMC4UE
|
||||||
|
- https://github.com/HAL9HARUKU/ueOSC
|
||||||
|
- https://github.com/HAL9HARUKU/VRMMapExporter
|
||||||
|
- https://github.com/vrm-c/UniVRM
|
||||||
|
|
||||||
|
[unity](https://unity.com/)で`VRMMapExporter`から`$model.vrmmap`を作る。ABPで読み込む。
|
||||||
|
|
||||||
|
`VMC4UE`は`$project.sln`を生成して`visual studio solution`でrebuildする。
|
||||||
|
|
||||||
|
ただし、この方法で表情を動かすことはできない。
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ git clone https://github.com/HAL9HARUKU/VMC4UE
|
||||||
|
$ cd VMC4UE
|
||||||
|
$ git reset --hard b5a6cf96e5928551d8e3e20b74705e3e8f22a1df
|
||||||
|
$ cd ..
|
||||||
|
|
||||||
|
# example
|
||||||
|
$ patch -u ./VMC4UE/VMC4UE/Source/VMC4UE/Source/VMC4UEBlueprintFunctionLibrary.cpp < VMC4UEBlueprintFunctionLibrary.cpp.patch
|
||||||
|
$ patch -u ./VMC4UE/VMC4UE/Source/VMC4UEEd/Source/VMC4UEBoneMappingAssetFactory.cpp < VMC4UEBoneMappingAssetFactory.cpp.patch
|
||||||
|
```
|
31
readme.md
@ -1,41 +1,20 @@
|
|||||||
# yui
|
# yui
|
||||||
|
|
||||||
- pixel streaming : https://ue.syui.ai
|
|
||||||
- support : `windows 64bit`
|
- support : `windows 64bit`
|
||||||
|
|
||||||
|title|推奨スペック|
|
|title|spec|
|
||||||
|---|---|
|
|---|---|
|
||||||
|cpu|AMD Ryzen 7 5700X|
|
|cpu|AMD Ryzen 7 5700X|
|
||||||
|memory|32GB / DDR4-3200 DIMM (PC4-25600)|
|
|memory|32GB / DDR4-3200 DIMM (PC4-25600)|
|
||||||
|gpu|GeForce RTX 4060Ti 8GB|
|
|gpu|GeForce RTX 4060Ti 8GB|
|
||||||
|storage|1TB M.2 NVMe SSD|
|
|storage|1TB M.2 NVMe SSD|
|
||||||
|
|
||||||
ハイスペックなパソコンが必要です。
|
|
||||||
|
|
||||||
## help
|
|
||||||
|
|
||||||
web板は同じ画面と操作が共有されています。他の人がログインしてプレイしているときは邪魔しないようにしましょう。
|
|
||||||
|
|
||||||
## download & start
|
|
||||||
|
|
||||||
ダウンロードは数時間かかります。
|
|
||||||
|
|
||||||
```sh
|
|
||||||
# ダウンロード
|
|
||||||
$ git clone https://git.syui.ai/ai/ue
|
|
||||||
$ cd ue
|
|
||||||
|
|
||||||
# 解凍
|
|
||||||
$ aunpack yui.zip
|
|
||||||
|
|
||||||
# 実行
|
|
||||||
$ ./Windows/yui.exe
|
|
||||||
```
|
|
||||||
|
|
||||||
## log
|
## log
|
||||||
|
|
||||||
|version|commit|
|
|version|commit|
|
||||||
|---|---|
|
|---|---|
|
||||||
|v0.1 β|世界を作っているところ|
|
|v0.1 β|world create|
|
||||||
|v0.2 β|物語を作った。webに対応|
|
|v0.2 β|support web|
|
||||||
|
|v0.3 β|support vmc|
|
||||||
|
|
||||||
|
|
||||||
|
7
slidev/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
*.local
|
||||||
|
.vite-inspect
|
||||||
|
.remote-assets
|
||||||
|
components.d.ts
|
3
slidev/.npmrc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# for pnpm
|
||||||
|
shamefully-hoist=true
|
||||||
|
auto-install-peers=true
|
15
slidev/README.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Welcome to [Slidev](https://github.com/slidevjs/slidev)!
|
||||||
|
|
||||||
|
To start the slide show:
|
||||||
|
|
||||||
|
- `npm install`
|
||||||
|
- `npm run dev`
|
||||||
|
- visit <http://localhost:3030>
|
||||||
|
|
||||||
|
Edit the [slides.md](./slides.md) to see the changes.
|
||||||
|
|
||||||
|
Learn more about Slidev at the [documentation](https://sli.dev/).
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ slidev build --base /slide
|
||||||
|
```
|
37
slidev/components/Counter.vue
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
count: {
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const counter = ref(props.count)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div flex="~" w="min" border="~ main rounded-md">
|
||||||
|
<button
|
||||||
|
border="r main"
|
||||||
|
p="2"
|
||||||
|
font="mono"
|
||||||
|
outline="!none"
|
||||||
|
hover:bg="gray-400 opacity-20"
|
||||||
|
@click="counter -= 1"
|
||||||
|
>
|
||||||
|
-
|
||||||
|
</button>
|
||||||
|
<span m="auto" p="2">{{ counter }}</span>
|
||||||
|
<button
|
||||||
|
border="l main"
|
||||||
|
p="2"
|
||||||
|
font="mono"
|
||||||
|
outline="!none"
|
||||||
|
hover:bg="gray-400 opacity-20"
|
||||||
|
@click="counter += 1"
|
||||||
|
>
|
||||||
|
+
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
16
slidev/netlify.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[build]
|
||||||
|
publish = "dist"
|
||||||
|
command = "npm run build"
|
||||||
|
|
||||||
|
[build.environment]
|
||||||
|
NODE_VERSION = "20"
|
||||||
|
|
||||||
|
[[redirects]]
|
||||||
|
from = "/.well-known/*"
|
||||||
|
to = "/.well-known/:splat"
|
||||||
|
status = 200
|
||||||
|
|
||||||
|
[[redirects]]
|
||||||
|
from = "/*"
|
||||||
|
to = "/index.html"
|
||||||
|
status = 200
|
17
slidev/package.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"name": "slidev",
|
||||||
|
"type": "module",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"build": "slidev build",
|
||||||
|
"dev": "slidev --open",
|
||||||
|
"export": "slidev export"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@slidev/cli": "^0.49.29",
|
||||||
|
"@slidev/theme-default": "latest",
|
||||||
|
"@slidev/theme-seriph": "latest",
|
||||||
|
"slidev-theme-eloc": "^1.0.2",
|
||||||
|
"vue": "^3.4.38"
|
||||||
|
}
|
||||||
|
}
|
27
slidev/pages/imported-slides.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Imported Slides
|
||||||
|
|
||||||
|
You can split your slides.md into multiple files and organize them as you want using the `src` attribute.
|
||||||
|
|
||||||
|
#### `slides.md`
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Page 1
|
||||||
|
|
||||||
|
Page 2 from main entry.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## src: ./subpage.md
|
||||||
|
```
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
#### `subpage.md`
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Page 2
|
||||||
|
|
||||||
|
Page 2 from another file.
|
||||||
|
```
|
||||||
|
|
||||||
|
[Learn more](https://sli.dev/guide/syntax.html#importing-slides)
|
135
slidev/slides.md
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
---
|
||||||
|
theme: eloc
|
||||||
|
class: text-center
|
||||||
|
highlighter: shiki
|
||||||
|
lineNumbers: false
|
||||||
|
info: |
|
||||||
|
## Slidev Starter Template
|
||||||
|
Presentation slides for developers.
|
||||||
|
|
||||||
|
Learn more at [Sli.dev](https://sli.dev)
|
||||||
|
drawings:
|
||||||
|
persist: false
|
||||||
|
transition: slide-left
|
||||||
|
title: Unreal Engine 5.5 | aiue
|
||||||
|
---
|
||||||
|
|
||||||
|
# `aiue`
|
||||||
|
|
||||||
|
物語は空と海に囲まれた西の都(みやこ)からはじまる...
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 配信で使える最新技術の紹介
|
||||||
|
|
||||||
|
### `unreal engine`
|
||||||
|
|
||||||
|
- vrm4u, vmc, livelink, streaming
|
||||||
|
- chatgpt, atproto
|
||||||
|
- `ai` + `ue`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `unreal engine`
|
||||||
|
|
||||||
|
- ue 5.5.0p
|
||||||
|
- ue 5.4.4
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `vrm4u`
|
||||||
|
|
||||||
|
キャラクターを表示しよう
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`vmc`と`livelink`で体の動きを反映
|
||||||
|
|
||||||
|
- vmcはABP
|
||||||
|
- livelinkはCBP
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `web browser`
|
||||||
|
|
||||||
|
WBPからwebを使おう
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
- widget3dをworldに表示させると画質が悪いので`EngineMaterials/Widget3DPassThrough`以外のmaterialを使います
|
||||||
|
|
||||||
|
<iframe src="https://blueprintue.com/render/-49_059w/"></iframe>
|
||||||
|
|
||||||
|
https://blueprintue.com/blueprint/-49_059w/
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `pixel streaming`
|
||||||
|
|
||||||
|
webでゲーム配信や操作ができる
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ git clone https://github.com/EpicGamesExt/PixelStreamingInfrastructure
|
||||||
|
$ cd ./PixelStreamingInfrastructure/SignallingWebServer/platform_scripts/cmd/
|
||||||
|
$ ./Start_SignallingServer_nopublic.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `atproto`
|
||||||
|
|
||||||
|
blueskyが使っているprotocol
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `game animation sample`
|
||||||
|
|
||||||
|
キャラクターの基本操作をカスタマイズ
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `city sample`
|
||||||
|
|
||||||
|
人や車が動く最先端の街
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `ultra dynamic sky`
|
||||||
|
|
||||||
|
- `sky atmoshpere` + `volumetric cloud`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## `whisper` + `chatgpt` + `elevenlabs`
|
||||||
|
|
||||||
|
キャラ設定と会話
|
||||||
|
|
||||||
|
- whisper : RuntimeSpeechRecognizer
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# perplexity.ai
|
||||||
|
$ curl -X POST "https://api.elevenlabs.io/v1/text-to-speech/VOICE_ID" \
|
||||||
|
-H "xi-api-key: YOUR_API_KEY" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"text": "Hello world!",
|
||||||
|
"model_id": "eleven_monolingual_v1",
|
||||||
|
"voice_settings": {
|
||||||
|
"stability": 0.5,
|
||||||
|
"similarity_boost": 0.5
|
||||||
|
}
|
||||||
|
}' \
|
||||||
|
--output output.mp3
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
@syui.ai
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<img src="https://yui.syui.ai/icon/ai.svg" width="50px">
|
||||||
|
<!--
|
||||||
|
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7a/Bluesky_Logo.svg/1200px-Bluesky_Logo.svg.png" width="30px">
|
||||||
|
-->
|
12
slidev/snippets/external.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/* eslint-disable no-console */
|
||||||
|
|
||||||
|
// #region snippet
|
||||||
|
// Inside ./snippets/external.ts
|
||||||
|
export function emptyArray<T>(length: number) {
|
||||||
|
return Array.from<T>({ length })
|
||||||
|
}
|
||||||
|
// #endregion snippet
|
||||||
|
|
||||||
|
export function sayHello() {
|
||||||
|
console.log('Hello from snippets/external.ts')
|
||||||
|
}
|
7
slidev/vercel.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"rewrites": [
|
||||||
|
{ "source": "/(.*)", "destination": "/index.html" }
|
||||||
|
],
|
||||||
|
"buildCommand": "npm run build",
|
||||||
|
"outputDirectory": "dist"
|
||||||
|
}
|
BIN
texture/T__02.PNG
Normal file
After Width: | Height: | Size: 63 KiB |
BIN
verse/bgm/aiend.mp3
Normal file
BIN
verse/bgm/aiend.wav
Normal file
BIN
verse/bgm/aihouse.mp3
Normal file
BIN
verse/bgm/aihouse.wav
Normal file
BIN
verse/bgm/aiverse.mp3
Normal file
BIN
verse/bgm/aiverse.wav
Normal file
BIN
verse/bgm/test.wav
Normal file
BIN
verse/img/aiverse.png
Normal file
After Width: | Height: | Size: 95 KiB |
BIN
verse/img/ep.mdp
Normal file
BIN
verse/img/ep.png
Normal file
After Width: | Height: | Size: 433 KiB |
BIN
verse/img/fly.gif
Normal file
After Width: | Height: | Size: 117 KiB |
BIN
verse/img/mode_ai.png
Normal file
After Width: | Height: | Size: 476 KiB |
BIN
verse/img/mode_normal.png
Normal file
After Width: | Height: | Size: 432 KiB |
BIN
verse/img/pomudachi.gif
Normal file
After Width: | Height: | Size: 145 KiB |
BIN
verse/img/recoder.gif
Normal file
After Width: | Height: | Size: 252 KiB |
BIN
verse/img/shinryu.png
Normal file
After Width: | Height: | Size: 202 KiB |
BIN
verse/img/ue.mdp
Normal file
BIN
verse/img/ue.png
Normal file
After Width: | Height: | Size: 561 KiB |
BIN
verse/img/wa.png
Normal file
After Width: | Height: | Size: 140 KiB |
BIN
verse/img/wall.png
Normal file
After Width: | Height: | Size: 133 KiB |
16
verse/md/ep.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# syui・ai
|
||||||
|
|
||||||
|
(シュイ・アイ)
|
||||||
|
|
||||||
|
THE FUZZY ONE
|
||||||
|
|
||||||
|
|title|body|
|
||||||
|
|---|---|
|
||||||
|
|nickname|syai|
|
||||||
|
|age|∞|
|
||||||
|
|height|123cm|
|
||||||
|
|birthday|1/23|
|
||||||
|
|lang|ja & en|
|
||||||
|
|text|「hello ai !」 一つの言葉しか覚えられない。自分やリスナーのことをアイと呼ぶ。世界を作るのが趣味。普段は地球を歩き回っている。|
|
||||||
|
|en|"Hello Ai!" I can only remember one word. I call myself and my listeners Ai. My hobby is creating worlds. I usually walk around the Earth.|
|
||||||
|
|
54
verse/md/ue.md
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
# Unreal Engine 5.4 | 初めてのゲーム制作、世界を作る
|
||||||
|
|
||||||
|
## vrm4u
|
||||||
|
|
||||||
|
キャラクターを表示しよう。
|
||||||
|
|
||||||
|
## game animation sample
|
||||||
|
|
||||||
|
今後はこの形式が基本になりそう。
|
||||||
|
|
||||||
|
## city sample
|
||||||
|
|
||||||
|
最初に難易度と負荷を高くする。
|
||||||
|
|
||||||
|
## sky atmoshpere + volumetric cloud
|
||||||
|
|
||||||
|
`dynamic volumetric sky -> ultra dynamic sky`
|
||||||
|
|
||||||
|
## whisper + chatgpt + elevenlabs
|
||||||
|
|
||||||
|
- whisper : RuntimeSpeechRecognizer
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# perplexity.ai
|
||||||
|
$ curl https://api.openai.com/v1/chat/completions \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Authorization: Bearer YOUR_API_KEY" \
|
||||||
|
-d '{
|
||||||
|
"model": "gpt-4o-mini",
|
||||||
|
"messages": [{"role": "user", "content": "Your question here"}],
|
||||||
|
"temperature": 0.7
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# perplexity.ai
|
||||||
|
$ curl -X POST "https://api.elevenlabs.io/v1/text-to-speech/VOICE_ID" \
|
||||||
|
-H "xi-api-key: YOUR_API_KEY" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"text": "Hello world!",
|
||||||
|
"model_id": "eleven_monolingual_v1",
|
||||||
|
"voice_settings": {
|
||||||
|
"stability": 0.5,
|
||||||
|
"similarity_boost": 0.5
|
||||||
|
}
|
||||||
|
}' \
|
||||||
|
--output output.mp3
|
||||||
|
```
|
||||||
|
|
||||||
|
## ue vs unity
|
||||||
|
|
||||||
|
ueは手順通りやっても動くことは稀。つまり、動かない。そのため情報も少ない。unityがおすすめ。
|
||||||
|
|
BIN
verse/music/aidream.mp3
Normal file
BIN
verse/music/aimoon.mp3
Normal file
BIN
verse/music/aimoon.wav
Normal file
BIN
verse/music/aipalette.mp3
Normal file
26
verse/readme.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# aiverse
|
||||||
|
|
||||||
|
aiverse project.
|
||||||
|
|
||||||
|
- https://youtube.com/@syai
|
||||||
|
|
||||||
|
## AI
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"music": "https://suno.com/@syui",
|
||||||
|
"anime": "https://domoai.app",
|
||||||
|
"3d": "https://tripo3d.ai"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## ref
|
||||||
|
|
||||||
|
- [octoverse](https://octoverse.github.com/)
|
||||||
|
- [hololive](https://hololive.hololivepro.com/talents?gp=myth)
|
||||||
|
|
||||||
|
##
|
||||||
|
|
||||||
|
character, lyrics, composition, illustrations, game production, modeling, etc.
|
||||||
|
|
||||||
|
© syui
|