Guter Code-Rig-Editor, aber er braucht Hilfe [geschlossen]HTML

HTML-Programmierer
Anonymous
 Guter Code-Rig-Editor, aber er braucht Hilfe [geschlossen]

Post by Anonymous »

Hier der Code, der repariert werden muss. Ich muss gerade für 5 Tage weg. Wenn Sie ihn reparieren können, wäre das großartig, aber hier ist die bessere, aber keine vollständige Korrekturversion. Hinweis: Bitte stimmen Sie nicht ab. Wenn Sie ihn reparieren können, tun Sie dies bitte und können Sie einen Kommentar abgeben, z. B. „Ist es möglich und dies ist kein Backup?“

Code: Select all

let scene, camera, renderer;
let controls, transformControls;
let chicken;
let bones = [];
let boneDots = [];
let frames = [];
let frameTimes = [];
let undoStack = [];
let redoStack = [];
let restPose = [];
let playing = false;
let playIndex = 0;
let playTimer = 0;
let last = performance.now();
const raycaster = new THREE.Raycaster();
raycaster.params.Sprite.threshold = 1.2;
const pointer = new THREE.Vector2();
let isTouching = false;
let lastTouchY = 0;
/* ================= INIT ================= */
init();
loadChicken();
animate();

function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0x444444);
camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.1, 1000);
camera.position.set(0, 3, 8);
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(innerWidth, innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.enablePan = true;
transformControls = new THREE.TransformControls(camera, renderer.domElement);
transformControls.addEventListener("dragging-changed", e => {
controls.enabled = !e.value;
});
scene.add(transformControls);
scene.add(new THREE.AmbientLight(0xffffff, 0.7));
const d = new THREE.DirectionalLight(0xffffff, 0.8);
d.position.set(5, 10, 5);
scene.add(d);
renderer.domElement.addEventListener("pointerdown", onPointerDown, {
passive: false
});
renderer.domElement.addEventListener("pointermove", onPointerMove, {
passive: false
});
renderer.domElement.addEventListener("pointerup", () => isTouching = false);
window.addEventListener("resize", () => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
}
/* ================= LOAD ================= */
function loadChicken() {
const loader = new THREE.FBXLoader();
const tex = new THREE.TextureLoader();
loader.load("https://itswardengod.github.io/wardengame/Chicken.FBX", obj => {
chicken = obj;
chicken.scale.setScalar(0.03);
const main = tex.load("https://itswardengod.github.io/wardengame/Main.png");
const alpha = tex.load("https://itswardengod.github.io/wardengame/Opacity.png");
obj.traverse(c => {
if (c.isMesh) {
c.material.map = main;
c.material.alphaMap = alpha;
c.material.alphaTest = 0.5;
c.material.side = THREE.DoubleSide;
}
if (c.isBone) {
bones.push(c);
restPose.push(c.quaternion.clone());
createBoneDot(c);
}
});
scene.add(chicken);
});
}
/* ================= BONE DOT ================= */
function createBoneDot(bone) {
const mat = new THREE.SpriteMaterial({
color: 0xff5555,
depthTest: false
});
const s = new THREE.Sprite(mat);
s.scale.set(1.6, 1.6, 1.6); // BIGGER FOR TOUCH
s.renderOrder = 999;
bone.add(s);
boneDots.push({
bone,
sprite: s
});
}
/* ================= POINTER ================= */
function onPointerDown(e) {
isTouching = true;
lastTouchY = e.clientY;
pointer.x = (e.clientX / innerWidth) * 2 - 1;
pointer.y = -(e.clientY / innerHeight) * 2 + 1;
raycaster.setFromCamera(pointer, camera);
const hits = raycaster.intersectObjects(boneDots.map(b => b.sprite), true);
if (hits.length) {
const hit = boneDots.find(b => b.sprite === hits[0].object);
transformControls.attach(hit.bone);
e.preventDefault();
} else {
transformControls.detach();
}
}

function onPointerMove(e) {
if (!isTouching) return;
// SINGLE FINGER DRAG = ZOOM
if (e.pointerType === "touch" && e.buttons === 1 && !transformControls.dragging) {
const dy = e.clientY - lastTouchY;
camera.position.addScaledVector(
camera.getWorldDirection(new THREE.Vector3()).negate(),
dy * 0.01
);
lastTouchY = e.clientY;
e.preventDefault();
}
}
/* ================= FRAMES ================= */
function snapshot() {
return bones.map(b =>  b.quaternion.clone());
}

function saveFrame() {
undoStack.push({
frames: [...frames],
times: [...frameTimes]
});
redoStack.length = 0;
frames.push(snapshot());
frameTimes.push(parseFloat(frameTime.value) || 0.4);
rebuildTimeline();
}

function nextFrame() {
if (!frames.length) return;
frames.at(-1).forEach((q, i) => bones[i].quaternion.copy(q));
}

function rebuildTimeline() {
timeline.innerHTML = "";
frames.forEach((_, i) => {
const d = document.createElement("div");
d.className = "frame";
d.textContent = i;
d.onclick = () => frames[i].forEach((q, b) => bones[b].quaternion.copy(q));
timeline.appendChild(d);
});
}
/* ================= UNDO ================= */
function undo() {
if (!undoStack.length) return;
redoStack.push({
frames: [...frames],
times: [...frameTimes]
});
({
frames,
frameTimes
} = undoStack.pop());
rebuildTimeline();
}

function redo() {
if (!redoStack.length) return;
undoStack.push({
frames: [...frames],
times: [...frameTimes]
});
({
frames,
frameTimes
} = redoStack.pop());
rebuildTimeline();
}
/* ================= RESET ================= */
function resetRig() {
bones.forEach((b, i) => b.quaternion.copy(restPose[i]));
}
/* ================= ANIMATION ================= */
function playAnimation() {
if (frames.length < 2) return;
playing = true;
playIndex = 0;
playTimer = 0;
}

function updateAnimation(dt) {
if (!playing) return;
playTimer += dt;
const d = frameTimes[playIndex];
if (playTimer >= d) {
playTimer = 0;
playIndex++;
if (playIndex >= frames.length - 1) {
playing = false;
return;
}
}
const a = playTimer / d;
bones.forEach((b, i) => b.quaternion.slerpQuaternions(
frames[playIndex][i],
frames[playIndex + 1][i], a));
}
/* ================= EXPORT ================= */
function exportGLTF() {
const tracks = [];
let t = 0;
const times = [0];
frameTimes.forEach(d => {
t += d;
times.push(t);
});
bones.forEach((bone, i) => {
const v = [];
frames.forEach(f => {
const q = f[i];
v.push(q.x, q.y, q.z, q.w);
});
tracks.push(new THREE.QuaternionKeyframeTrack(
bone.name + ".quaternion", times, v));
});
const clip = new THREE.AnimationClip("RigAnimation", -1, tracks);
chicken.animations = [clip];
new THREE.GLTFExporter().parse(chicken, g =>  {
const a = document.createElement("a");
a.href = URL.createObjectURL(new Blob([JSON.stringify(g)], {
type: "application/json"
}));
a.download = "rigged_animation.gltf";
a.click();
}, {
animations: [clip]
});
}
/* ================= LOOP ================= */
function animate() {
requestAnimationFrame(animate);
const now = performance.now(),
dt = (now - last) / 1000;
last = now;
updateAnimation(dt);
controls.update();
renderer.render(scene, camera);
}

function setMode(m) {
transformControls.setMode(m);
}

Code: Select all

body {
margin: 0;
overflow: hidden;
background: #222;
font-family: sans-serif;
}

#ui {
position: absolute;
bottom: 0;
width: 100%;
background: rgba(0, 0, 0, 0.85);
padding: 6px;
display: flex;
flex-wrap: wrap;
}

button,
input {
font-size: 16px;
margin: 4px;
}

#timeline {
display: flex;
overflow-x: auto;
width: 100%;
}

.frame {
width: 36px;
height: 36px;
background: #444;
margin: 4px;
border-radius: 4px;
text-align: center;
line-height: 36px;
color: white;
}

label {
color: white;
}

Code: Select all

Chicken Rig Editor








 Rotate Move Add Frame Next Frame Undo Redo Rig Reset  Δt  Play Export GLTF



Und hier ein OK, das nicht so gut, aber fester ist

Code: Select all

/* ================= GLOBALS ================= */
let scene, camera, renderer;
let controls, transformControls;
let chicken;
let bones = [];
let boneDots = [];
let frames = [];
let frameTimes = [];
let undoStack = [];
let redoStack = [];
let restPose = [];
let playing = false;
let playIndex = 0;
let playTimer = 0;
let last = performance.now();
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
/* ================= INIT ================= */
init();
loadChicken();
animate();

function init() {
scene = new THREE.Scene();
scene.background = new THREE.Color(0x444444);
camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 0.1, 1000);
camera.position.set(0, 3, 8);
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(innerWidth, innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
transformControls = new THREE.TransformControls(camera, renderer.domElement);
transformControls.addEventListener("dragging-changed", e =>  {
controls.enabled = !e.value;
});
scene.add(transformControls);
scene.add(new THREE.AmbientLight(0xffffff, 0.7));
const dirLight = new THREE.DirectionalLight(0xffffff, 0.8);
dirLight.position.set(5, 10, 5);
scene.add(dirLight);
renderer.domElement.addEventListener("pointerdown", onPointerDown);
document.addEventListener("mousemove", e => {
mouse.x = (e.clientX / innerWidth) * 2 - 1;
mouse.y = -(e.clientY / innerHeight) * 2 + 1;
});
window.addEventListener("resize", () => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
}
/* ================= LOAD CHICKEN ================= */
function loadChicken() {
const loader = new THREE.FBXLoader();
const texLoader = new THREE.TextureLoader();
loader.load(
"https://itswardengod.github.io/wardengame/Chicken.FBX",
obj => {
chicken = obj;
chicken.scale.setScalar(0.03);
const mainTex = texLoader.load("https://itswardengod.github.io/wardengame/Main.png");
const opacityTex = texLoader.load("https://itswardengod.github.io/wardengame/Opacity.png");
obj.traverse(child => {
if (child.isMesh) {
child.material.map = mainTex;
child.material.alphaMap = opacityTex;
child.material.alphaTest = 0.5;
child.material.side = THREE.DoubleSide;
}
if (child.isBone) {
bones.push(child);
restPose.push(child.quaternion.clone());
createBoneDot(child);
}
});
scene.add(chicken);
}
);
}
/* ================= BONE DOTS ================= */
function createBoneDot(bone) {
const spriteMat = new THREE.SpriteMaterial({
color: 0xff4444,
depthTest: false,
depthWrite: false
});
const sprite = new THREE.Sprite(spriteMat);
sprite.scale.set(1, 1, 1);
sprite.renderOrder = 999;
bone.add(sprite);
boneDots.push({
bone,
sprite
});
}
/* ================= SELECTION ================= */
function onPointerDown(e) {
raycaster.setFromCamera(mouse, camera);
const hits = raycaster.intersectObjects(boneDots.map(b => b.sprite));
if (hits.length) {
transformControls.attach(
boneDots.find(b => b.sprite === hits[0].object).bone
);
}
}
/* ================= FRAMES ================= */
function snapshot() {
return bones.map(b => b.quaternion.clone());
}

function saveFrame() {
undoStack.push({
frames: [...frames],
times: [...frameTimes]
});
redoStack.length = 0;
frames.push(snapshot());
frameTimes.push(parseFloat(frameTime.value) || 0.4);
rebuildTimeline();
}

function nextFrame() {
if (!frames.length) return;
frames[frames.length - 1].forEach((q, i) => bones[i].quaternion.copy(q));
}

function rebuildTimeline() {
timeline.innerHTML = "";
frames.forEach((_, i) => {
const d = document.createElement("div");
d.className = "frame";
d.textContent = i;
d.onclick = () => frames[i].forEach((q, b) => bones[b].quaternion.copy(q));
timeline.appendChild(d);
});
}
/* ================= UNDO / REDO ================= */
function undo() {
if (!undoStack.length) return;
redoStack.push({
frames: [...frames],
times: [...frameTimes]
});
const s = undoStack.pop();
frames = s.frames;
frameTimes = s.times;
rebuildTimeline();
}

function redo() {
if (!redoStack.length) return;
undoStack.push({
frames: [...frames],
times: [...frameTimes]
});
const s = redoStack.pop();
frames = s.frames;
frameTimes = s.times;
rebuildTimeline();
}
/* ================= RESET ================= */
function resetRig() {
bones.forEach((b, i) => b.quaternion.copy(restPose[i]));
}
/* ================= ANIMATION ================= */
function playAnimation() {
if (frames.length <  2) return;
playing = true;
playIndex = 0;
playTimer = 0;
}

function updateAnimation(dt) {
if (!playing) return;
playTimer += dt;
const dur = frameTimes[playIndex];
if (playTimer >= dur) {
playTimer = 0;
playIndex++;
if (playIndex >= frames.length - 1) {
playing = false;
return;
}
}
const a = playTimer / dur;
bones.forEach((b, i) => {
b.quaternion.slerpQuaternions(
frames[playIndex][i],
frames[playIndex + 1][i],
a
);
});
}
/* ================= EXPORT ================= */
function exportGLTF() {
const tracks = [];
let t = 0;
const times = [0];
frameTimes.forEach(d => {
t += d;
times.push(t);
});
bones.forEach((bone, i) => {
const values = [];
frames.forEach(f => {
const q = f[i];
values.push(q.x, q.y, q.z, q.w);
});
tracks.push(new THREE.QuaternionKeyframeTrack(
bone.name + ".quaternion", times, values
));
});
const clip = new THREE.AnimationClip("RigAnimation", -1, tracks);
chicken.animations = [clip];
new THREE.GLTFExporter().parse(chicken, g => {
const a = document.createElement("a");
a.href = URL.createObjectURL(new Blob([JSON.stringify(g)], {
type: "application/json"
}));
a.download = "rigged_animation.gltf";
a.click();
}, {
animations: [clip]
});
}
/* ================= LOOP ================= */
function animate() {
requestAnimationFrame(animate);
const now = performance.now();
const dt = (now - last) / 1000;
last = now;
updateAnimation(dt);
controls.update();
renderer.render(scene, camera);
}

function setMode(m) {
transformControls.setMode(m);
}

Code: Select all

body {
margin: 0;
overflow: hidden;
background: #222;
font-family: sans-serif;
}

#ui {
position: absolute;
bottom: 0;
width: 100%;
background: rgba(0, 0, 0, 0.85);
padding: 6px;
display: flex;
flex-wrap: wrap;
}

button,
input {
font-size: 16px;
margin: 4px;
}

#timeline {
display: flex;
overflow-x: auto;
width: 100%;
}

.frame {
width: 36px;
height: 36px;
background: #444;
margin: 4px;
border-radius: 4px;
text-align: center;
line-height: 36px;
color: white;
}

label {
color: white;
}

Code: Select all

Chicken Rig Editor







 Rotate Move Add Frame Next Frame Undo Redo Rig Reset  Δt   Play Export GLTF

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post