first commit

This commit is contained in:
2026-01-07 16:24:34 +00:00
commit 5c1399bb96
362 changed files with 59794 additions and 0 deletions

View File

@@ -0,0 +1,317 @@
/**
* Simplified Live2D SDK Wrapper
* Based on the working implementation from live2d-master
*/
class Live2DModel {
constructor() {
this.model = null;
this.motionManager = null;
this.eyeBlink = null;
this.pose = null;
this.physics = null;
this.modelMatrix = null;
this.dragManager = null;
this.isInitialized = false;
this.isVisible = true;
this.alpha = 1.0;
}
// Load model from .moc file
loadModel(mocPath, callback) {
const request = new XMLHttpRequest();
request.open('GET', mocPath, true);
request.responseType = 'arraybuffer';
request.onload = () => {
if (request.status === 200) {
try {
this.model = window.Live2DModelWebGL.loadModel(request.response);
if (this.model) {
this.initializeModel();
callback(this);
} else {
console.error('Failed to load Live2D model from:', mocPath);
}
} catch (error) {
console.error('Error loading Live2D model:', error);
}
} else {
console.error('Failed to fetch model file:', mocPath);
}
};
request.onerror = () => {
console.error('Network error loading model:', mocPath);
};
request.send();
}
// Initialize model components
initializeModel() {
if (!this.model) return;
// Initialize model matrix
this.modelMatrix = new window.L2DModelMatrix(
this.model.getCanvasWidth(),
this.model.getCanvasHeight()
);
this.modelMatrix.setWidth(2);
this.modelMatrix.setCenterPosition(0, 0);
// Initialize motion manager
this.motionManager = new window.L2DMotionManager();
// Initialize eye blink
this.eyeBlink = new window.L2DEyeBlink();
// Initialize pose
this.pose = window.L2DPose.load();
// Initialize physics
this.physics = window.L2DPhysics.load();
// Initialize drag manager
this.dragManager = new window.L2DTargetPoint();
this.isInitialized = true;
}
// Load texture
loadTexture(textureIndex, texturePath, callback) {
if (!this.model) return;
const img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = () => {
const gl = window.Live2D.getGL();
if (gl) {
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
gl.generateMipmap(gl.TEXTURE_2D);
gl.bindTexture(gl.TEXTURE_2D, null);
this.model.setTexture(textureIndex, texture);
if (callback) callback();
}
};
img.onerror = () => {
console.error('Failed to load texture:', texturePath);
};
img.src = texturePath;
}
// Load motion
loadMotion(motionPath, callback) {
const request = new XMLHttpRequest();
request.open('GET', motionPath, true);
request.responseType = 'arraybuffer';
request.onload = () => {
if (request.status === 200) {
try {
const motion = window.Live2DMotion.loadMotion(request.response);
if (motion && callback) {
callback(motion);
}
} catch (error) {
console.error('Error loading motion:', error);
}
}
};
request.send();
}
// Start motion
startMotion(motion, priority = 3) {
if (!this.motionManager || !motion) return;
this.motionManager.startMotionPrio(motion, priority);
}
// Set parameter value
setParamFloat(paramId, value, weight = 1.0) {
if (!this.model) return;
this.model.setParamFloat(paramId, value, weight);
}
// Get parameter value
getParamFloat(paramId) {
if (!this.model) return 0;
return this.model.getParamFloat(paramId);
}
// Update model
update() {
if (!this.isInitialized || !this.model) return;
// Update drag
if (this.dragManager) {
this.dragManager.update();
this.model.setDrag(this.dragManager.getX(), this.dragManager.getY());
}
// Update eye blink
if (this.eyeBlink) {
this.eyeBlink.updateParam(this.model);
}
// Update motion
if (this.motionManager) {
this.motionManager.updateParam(this.model);
}
// Update pose
if (this.pose) {
this.pose.updateParam(this.model);
}
// Update physics
if (this.physics) {
this.physics.updateParam(this.model);
}
// Update model
this.model.update();
}
// Draw model
draw() {
if (!this.isInitialized || !this.model || !this.isVisible) return;
const gl = window.Live2D.getGL();
if (!gl) return;
// Apply model matrix
if (this.modelMatrix) {
this.model.setMatrix(this.modelMatrix.getArray());
}
// Set alpha
this.model.setAlpha(this.alpha);
// Draw
this.model.draw();
}
// Set drag position
setDrag(x, y) {
if (this.dragManager) {
this.dragManager.setPoint(x, y);
}
}
// Hit test
hitTest(x, y, hitAreaName) {
if (!this.model) return false;
return this.model.hitTestSimple(hitAreaName, x, y);
}
// Release resources
release() {
if (this.model) {
this.model.release();
this.model = null;
}
this.isInitialized = false;
}
}
// Live2D Manager
class Live2DManager {
constructor() {
this.gl = null;
this.models = [];
this.currentModelIndex = 0;
this.isInitialized = false;
}
// Initialize WebGL context
setGL(gl) {
this.gl = gl;
window.Live2D.setGL(gl);
this.isInitialized = true;
}
// Get WebGL context
getGL() {
return this.gl;
}
// Create new model
createModel() {
return new Live2DModel();
}
// Add model
addModel(model) {
this.models.push(model);
return this.models.length - 1;
}
// Get model
getModel(index) {
if (index >= 0 && index < this.models.length) {
return this.models[index];
}
return null;
}
// Get current model
getCurrentModel() {
return this.getModel(this.currentModelIndex);
}
// Set current model
setCurrentModel(index) {
if (index >= 0 && index < this.models.length) {
this.currentModelIndex = index;
}
}
// Update all models
updateModels() {
this.models.forEach(model => {
if (model) {
model.update();
}
});
}
// Draw all models
drawModels() {
if (!this.gl) return;
this.gl.clearColor(0, 0, 0, 0);
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
this.models.forEach(model => {
if (model) {
model.draw();
}
});
}
// Release all models
releaseModels() {
this.models.forEach(model => {
if (model) {
model.release();
}
});
this.models = [];
}
}
// Export to global scope
window.Live2DManager = Live2DManager;
window.Live2DModel = Live2DModel;
// Global Live2D manager instance
window.live2dManager = new Live2DManager();

File diff suppressed because one or more lines are too long