mirror of
https://git.chinosk6.cn/chinosk/gkms-local.git
synced 2026-10-07 23:21:48 +07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76037b26f1 | ||
|
|
c07adf7a20 | ||
|
|
ebfede9093 | ||
|
|
047b584677 | ||
|
|
3c5c9ac9dd | ||
|
|
fcdf249b40 |
No files matched your search
+3
-3
@@ -15,8 +15,8 @@ android {
|
||||
applicationId "io.github.chinosk.gakumas.localify"
|
||||
minSdk 29
|
||||
targetSdk 34
|
||||
versionCode 12
|
||||
versionName "v3.4.0"
|
||||
versionCode 13
|
||||
versionName "v3.5.0"
|
||||
buildConfigField "String", "VERSION_NAME", "\"${versionName}\""
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
@@ -132,4 +132,4 @@ dependencies {
|
||||
implementation(libs.shadowhook)
|
||||
compileOnly(libs.xposed.api)
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#include "GyroEmu.hpp"
|
||||
#include "config/Config.hpp"
|
||||
#include <windows.h>
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
|
||||
namespace GakumasLocal::GyroEmu {
|
||||
using Quaternion = UnityResolve::UnityType::Quaternion;
|
||||
using Vector3 = UnityResolve::UnityType::Vector3;
|
||||
|
||||
static float pitch = 0, yaw = 0, roll = 0; // 度,Unity 相机欧拉角
|
||||
static POINT lastCursor{};
|
||||
static bool dragging = false;
|
||||
static auto lastTick = std::chrono::steady_clock::now();
|
||||
|
||||
static bool Down(int vk) { return (GetAsyncKeyState(vk) & 0x8000) != 0; }
|
||||
|
||||
void Reset() { pitch = yaw = roll = 0; }
|
||||
|
||||
static void PollInput() {
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
const float dt = (std::min)(std::chrono::duration<float>(now - lastTick).count(), 0.1f);
|
||||
lastTick = now;
|
||||
|
||||
const float sx = Config::gyroSensitivity * (Config::gyroInvertX ? -1.f : 1.f);
|
||||
const float sy = Config::gyroSensitivity * (Config::gyroInvertY ? -1.f : 1.f);
|
||||
|
||||
// 右键拖动:鼠标位移 -> yaw/pitch
|
||||
if (Down(VK_RBUTTON)) {
|
||||
POINT cur; GetCursorPos(&cur);
|
||||
if (dragging) {
|
||||
yaw += (cur.x - lastCursor.x) * 0.1f * sx;
|
||||
pitch += (cur.y - lastCursor.y) * 0.1f * sy;
|
||||
}
|
||||
lastCursor = cur;
|
||||
dragging = true;
|
||||
} else {
|
||||
dragging = false;
|
||||
}
|
||||
|
||||
// 小键盘:7/9 翻滚, 5 复位。4/6/8/2 是游戏自己拍摄页的镜头键,不占用
|
||||
const float step = 60.f * dt * Config::gyroSensitivity;
|
||||
if (Down(VK_NUMPAD7)) roll += step;
|
||||
if (Down(VK_NUMPAD9)) roll -= step;
|
||||
if (Down(VK_NUMPAD5)) Reset();
|
||||
|
||||
pitch = std::clamp(pitch, -89.f, 89.f);
|
||||
}
|
||||
|
||||
Quaternion Attitude() {
|
||||
PollInput();
|
||||
Quaternion q; q.Euler(pitch, yaw, roll);
|
||||
// 反汇编 VLGyro.get_gyroRotationRaw:raw = gyroBaseRotation * Quaternion(-a.x, -a.y, a.z, a.w);
|
||||
// CampusGyroController.Rotation = Inverse(raw@reset) * raw,base 被消掉,所以直接把相机欧拉角编码进 a 即可。
|
||||
return Quaternion(-q.x, -q.y, q.z, q.w);
|
||||
}
|
||||
|
||||
Vector3 Gravity() {
|
||||
// ponytail: 竖持手机时重力恒指向设备 -Y,VLGyro 没用到重力,够用
|
||||
return Vector3(0.f, -1.f, 0.f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "../deps/UnityResolve/UnityResolve.hpp"
|
||||
|
||||
// 用鼠标右键拖动 / 小键盘模拟手机陀螺仪姿态(PC 版无陀螺仪)
|
||||
namespace GakumasLocal::GyroEmu {
|
||||
// 读一次输入并返回当前 Input.gyro.attitude
|
||||
UnityResolve::UnityType::Quaternion Attitude();
|
||||
UnityResolve::UnityType::Vector3 Gravity();
|
||||
void Reset();
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,6 +1,7 @@
|
||||
#include "baseCamera.hpp"
|
||||
#include "camera.hpp"
|
||||
#include <thread>
|
||||
#include <cmath>
|
||||
#include "../Misc.hpp"
|
||||
#include "../BaseDefine.h"
|
||||
#include "../../platformDefine.hpp"
|
||||
@@ -411,6 +412,14 @@ namespace GKCamera {
|
||||
const auto currentY = targetPos.y;
|
||||
static auto lastRetY = currentY;
|
||||
|
||||
// NaN/Inf 防护:目标 Y 非法时保持上一次有效值,避免污染平滑队列后相机飞走
|
||||
if (!std::isfinite(currentY)) {
|
||||
return std::isfinite(lastRetY) ? lastRetY : 0.0f;
|
||||
}
|
||||
if (!std::isfinite(lastRetY)) {
|
||||
lastRetY = currentY;
|
||||
}
|
||||
|
||||
if (followModeY == FollowModeY::APPLY_Y) {
|
||||
lastRetY = currentY;
|
||||
return currentY;
|
||||
@@ -423,6 +432,10 @@ namespace GKCamera {
|
||||
recordsY.Push(currentY);
|
||||
}
|
||||
|
||||
if (!std::isfinite(currentAvg)) {
|
||||
return lastRetY;
|
||||
}
|
||||
|
||||
if (abs(currentY - currentAvg) < 0.02) {
|
||||
return lastRetY;
|
||||
}
|
||||
@@ -460,7 +473,17 @@ namespace GKCamera {
|
||||
|
||||
// 计算角色的右方向
|
||||
Vector3 up(0, 1, 0); // Y轴方向
|
||||
Vector3 right = forward.cross(up).Normalize();
|
||||
Vector3 right = forward.cross(up);
|
||||
|
||||
// 修正归一化:原 UnityResolve::Vector3::Normalize 除的是平方长度,且零向量会产出 NaN
|
||||
const auto rightLenSq = right.x * right.x + right.y * right.y + right.z * right.z;
|
||||
if (rightLenSq < 1e-8f) {
|
||||
// forward 与 up 平行/接近或为零向量,无法求右向,退化为仅高度偏移
|
||||
return Vector3(position.x, position.y + offset.y, position.z);
|
||||
}
|
||||
const auto invRightLen = 1.0f / std::sqrt(rightLenSq);
|
||||
right = Vector3(right.x * invRightLen, right.y * invRightLen, right.z * invRightLen);
|
||||
|
||||
Vector3 fwd = forward;
|
||||
Vector3 pos = position;
|
||||
|
||||
|
||||
@@ -19,6 +19,10 @@ namespace GakumasLocal::Config {
|
||||
bool dumpText = false;
|
||||
bool dumpRuntimeTexture = false;
|
||||
bool enableFreeCamera = false;
|
||||
bool enableGyroEmu = false;
|
||||
float gyroSensitivity = 1.0f;
|
||||
bool gyroInvertX = false;
|
||||
bool gyroInvertY = false;
|
||||
int targetFrameRate = 0;
|
||||
bool unlockAllLive = false;
|
||||
bool unlockAllLiveCostume = false;
|
||||
@@ -77,6 +81,10 @@ namespace GakumasLocal::Config {
|
||||
GetConfigItem(dumpRuntimeTexture);
|
||||
GetConfigItem(targetFrameRate);
|
||||
GetConfigItem(enableFreeCamera);
|
||||
GetConfigItem(enableGyroEmu);
|
||||
GetConfigItem(gyroSensitivity);
|
||||
GetConfigItem(gyroInvertX);
|
||||
GetConfigItem(gyroInvertY);
|
||||
GetConfigItem(unlockAllLive);
|
||||
GetConfigItem(unlockAllLiveCostume);
|
||||
GetConfigItem(enableLiveCustomeDress);
|
||||
@@ -135,6 +143,10 @@ namespace GakumasLocal::Config {
|
||||
SetConfigItem(dumpRuntimeTexture);
|
||||
SetConfigItem(targetFrameRate);
|
||||
SetConfigItem(enableFreeCamera);
|
||||
SetConfigItem(enableGyroEmu);
|
||||
SetConfigItem(gyroSensitivity);
|
||||
SetConfigItem(gyroInvertX);
|
||||
SetConfigItem(gyroInvertY);
|
||||
SetConfigItem(unlockAllLive);
|
||||
SetConfigItem(unlockAllLiveCostume);
|
||||
SetConfigItem(enableLiveCustomeDress);
|
||||
|
||||
@@ -15,6 +15,10 @@ namespace GakumasLocal::Config {
|
||||
extern bool dumpText;
|
||||
extern bool dumpRuntimeTexture;
|
||||
extern bool enableFreeCamera;
|
||||
extern bool enableGyroEmu;
|
||||
extern float gyroSensitivity;
|
||||
extern bool gyroInvertX;
|
||||
extern bool gyroInvertY;
|
||||
extern int targetFrameRate;
|
||||
extern bool unlockAllLive;
|
||||
extern bool unlockAllLiveCostume;
|
||||
|
||||
Reference in new issue
Block a user