first commit
This commit is contained in:
317
public/pio/static/live2d-sdk/live2d-wrapper.js
Normal file
317
public/pio/static/live2d-sdk/live2d-wrapper.js
Normal 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();
|
||||
Reference in New Issue
Block a user