Skip to content
Snippets Groups Projects
Select Git revision
  • 561186a27e5443cf977494752778ffb25d4f4682
  • main default
  • hsh-MOODLE_404+
  • hsh_3.10
  • master protected
  • v1.4.7
  • v1.4.6
  • v1.4.5
  • v1.4.3
  • v1.4.1
  • v1.4
  • v1.3r2
  • v1.3
  • v1.2
14 results

forward_form.php

Blame
  • SimulationSettings.ts 12.85 KiB
    import * as THREE from 'three';
    import { GUI } from 'dat.gui';
    import { picked, PipelineGUI } from '../core/Pipeline';
    import { BendingSpring, ShearSpring, Spring, SpringConstants, StructuralSpring,  } from './cgPhysix/Springs';
    import { Particle } from './cgPhysix/particle';
    
    
    class World {
        public static readonly G = 9.807;
    
        public static derivation(x: Array<number>): Array<number> {
    
            let xDot = new Array<number>(x.length);
    
            for (let i = 0; i < x.length; i += 6) {
                xDot[i] = x[i + 3];
                xDot[i + 1] = x[i + 4];
                xDot[i + 2] = x[i + 5];
                xDot[i + 3] = 0;
                xDot[i + 4] = -.01;
                xDot[i + 5] = 0;
            }
    
            return xDot;
        }
    
    
    }
    
    
    class SimulationSettings implements PipelineGUI {
    
        public static container: THREE.Group = new THREE.Group();
    
        // cloth settings
        public static readonly MAX_TOTAL_MASS = 10;
        public static readonly MIN_TOTAL_MASS = 0.1;
    
        public static readonly MAX_WIDTH = 5;
        public static readonly MIN_WIDTH = 0.01;
    
        public static readonly MAX_HEIGHT = 2;
        public static readonly MIN_HEIGHT = 0.01;
    
        public static readonly MAX_RESOLUTION = 20;
        public static readonly MIN_RESOLUTION = 2;
    
        public static totalMass: number = 1;
        public static width: number = 1;
        public static height: number = 1;
        public static resolution: number = 5;
        public static externalForce: THREE.Vector3 = new THREE.Vector3(0, 0, 0);
    
        // particls
        public static pList = new Array<Array<Particle>>();
        public static pColorDefault: number = 0xffffff;
        public static pColorNoPhysix: number = 0xff00ff;
    
        // springs
        public static readonly MAX_CONSTANT = 10;
        public static readonly MIN_CONSTANT = 0.1;
    
        public static sList = new Array<Spring>();
        public static sConstants: SpringConstants = { structural: 1, shear: 1, bend: 1 };
        public static sColorStructural: number = 0xff0000;
        public static sColorShear: number = 0x00ff00;
        public static sColorBend: number = 0x0000ff;
    
        // integrator
        public static readonly INTEGRATOR_TYPES = ['Euler', 'Midpoint', 'RungeKutta'];
        public static readonly STEP_SIZE = ['Fixed', 'Adaptive'];
    
        public static integratorType: string = 'Euler';
        public static stepSize: string = 'Fixed';
    
        public static generateTextile(): void {
            // 1. reset pList
            SimulationSettings.pList = new Array<Array<Particle>>();
    
            // 2. generate particles
            for (let i = 0; i < SimulationSettings.resolution; i++) {
                SimulationSettings.pList[i] = new Array<Particle>();
                for (let j = 0; j < SimulationSettings.resolution; j++) {
    
                    const p = new Particle({
                        position: new THREE.Vector3(
                            SimulationSettings.width * (i / SimulationSettings.resolution) - SimulationSettings.width / 2,
                            SimulationSettings.height * (j / SimulationSettings.resolution) - SimulationSettings.height / 2,
                            0),
                        velocity: new THREE.Vector3(0, 0, 0),
                        mass: SimulationSettings.totalMass / (SimulationSettings.resolution * SimulationSettings.resolution),
                        usePhysics: true,
                        references: [],
                        radius: 0,
                        color: SimulationSettings.pColorDefault,
                        wireframe: true
                    });
                    SimulationSettings.pList[i][j] = p;
                }
            }
    
            for (let i = 0; i < SimulationSettings.resolution; i++) {
                SimulationSettings.pList[i][SimulationSettings.resolution - 1].usePhysics = false;
            }
    
            // 3. set particle mass and color
            SimulationSettings.changedParticleSize();
            SimulationSettings.changedParticleColor();
    
            // 4. add particles to container
            const pLinList = new Array<THREE.Mesh>();
            SimulationSettings.pList.forEach(pSub => {
                pSub.forEach(p => {
                    pLinList.push(p.mesh);
                });
            });
    
            // 5. reset sList
            SimulationSettings.sList = new Array<Spring>();
    
            // 6. generate springs
            for (let i = 0; i < SimulationSettings.resolution; i++) {
                for (let j = 0; j < SimulationSettings.resolution; j++) {
    
                    // structural springs (horizontal)
                    if (i < SimulationSettings.resolution - 1) {
                        const pA = SimulationSettings.pList[i][j];
                        const pB = SimulationSettings.pList[i + 1][j];
    
                        const s = new StructuralSpring({
                            positionA: pA.position,
                            positionB: pB.position,
                            constants: SimulationSettings.sConstants,
                            color: SimulationSettings.sColorStructural,
                        });
                        SimulationSettings.sList.push(s);
    
                        pA.references.push(s);
                        pB.references.push(s);
                    }
    
                    // structural springs (vertical)
                    if (j < SimulationSettings.resolution - 1) {
                        const pA = SimulationSettings.pList[i][j];
                        const pB = SimulationSettings.pList[i][j + 1];
    
                        const s = new StructuralSpring({
                            positionA: pA.position,
                            positionB: pB.position,
                            constants: SimulationSettings.sConstants,
                            color: SimulationSettings.sColorStructural,
                        });
                        SimulationSettings.sList.push(s);
    
                        pA.references.push(s);
                        pB.references.push(s);
                    }
    
    
                    // // shear springs
                    // if (j < SimulationSettings.resolution - 1) {
                    //     const s = new ShearSpring(SimulationSettings.pList[i][j], SimulationSettings.pList[i][j + 1], SimulationSettings.sConstants.shear);
                    //     SimulationSettings.sList.push(s);
                    // }
    
                    // // bending springs
                    // if (i < SimulationSettings.resolution - 1 && j < SimulationSettings.resolution - 1) {
                    //     const s = new BendingSpring(SimulationSettings.pList[i][j], SimulationSettings.pList[i + 1][j + 1], SimulationSettings.sConstants.bend);
                    //     SimulationSettings.sList.push(s);
                    // }
                }
            }
    
            // 7. add springs to container
            const sLinList = new Array<THREE.Line>();
            SimulationSettings.sList.forEach(s => {
                sLinList.push(s.line);
            });
    
            // 8. add particles and springs to container
            while (SimulationSettings.container.children.length > 0) {
                SimulationSettings.container.children.pop();
            }
    
            SimulationSettings.container.add(...pLinList, ...sLinList);
        }
    
        public static changedParticleSize(): void {
            // 1. calculate current mass
            const pCount = SimulationSettings.resolution * SimulationSettings.resolution;
            const pMass = SimulationSettings.totalMass / pCount;
    
            // 2. calculate max pSize
            const maxSize = Math.min(SimulationSettings.width, SimulationSettings.height);
    
            // 3. normalize pMass
            const pMassNorm = (pMass + SimulationSettings.MIN_TOTAL_MASS) /
                (SimulationSettings.MAX_TOTAL_MASS + SimulationSettings.MIN_TOTAL_MASS);
    
            // 4. calculate pSize
            const pSize = maxSize * pMassNorm;
    
            // 5. set pSize
            SimulationSettings.pList.forEach(pSub => { pSub.forEach(p => p.setRadius(pSize)) });
        }
    
        public static changedDimensions(): void {
            // 1. reset positions of particles
            for (let i = 0; i < SimulationSettings.resolution; i++) {
                for (let j = 0; j < SimulationSettings.resolution; j++) {
                    SimulationSettings.pList[i][j].setPosition(
                        SimulationSettings.width * (i / SimulationSettings.resolution) - SimulationSettings.width / 2,
                        SimulationSettings.height * (j / SimulationSettings.resolution) - SimulationSettings.height / 2,
                        0);
                }
            }
    
            // 2. set size based on particle mass
            SimulationSettings.changedParticleSize();
        }
    
        public static changedParticleColor(): void {
            // iterate over all particles and set color based on current internal state
            SimulationSettings.pList.forEach(pSub => {
                pSub.forEach(p => {
                    if (p.usePhysics) {
                        p.setColor(SimulationSettings.pColorDefault);
                    } else {
                        p.setColor(SimulationSettings.pColorNoPhysix);
                    }
                })
            });
        }
    
        public static changedSpringColor(): void {
            // iterate over all particles and set color based on current internal state
            SimulationSettings.sList.forEach(s => {
                if (s instanceof StructuralSpring) {
                    s.setColor(SimulationSettings.sColorStructural);
                } else if (s instanceof ShearSpring) {
                    s.setColor(SimulationSettings.sColorShear);
                } else if (s instanceof BendingSpring) {
                    s.setColor(SimulationSettings.sColorBend);
                }
            });
        }
    
        public static switchParticlePhysics(): void {
            // 1. is picked object not null
            if (!picked) {
                return;
            }
    
            // 2. compare mesh to all particles => find particle and change usePhysics
            SimulationSettings.pList.forEach(pSub => {
                pSub.forEach(p => {
                    if (p.mesh === picked) {
                        p.usePhysics = !p.usePhysics;
                        p.setColor(p.usePhysics ? SimulationSettings.pColorDefault 
                            : SimulationSettings.pColorNoPhysix);
                    }
                })
            });
        }
    
        // callback overrides by other classes
        public callbackSpringColorStructural(_value: number): void { }
        public callbackSpringColorShear(_value: number): void { }
        public callbackSpringColorBend(_value: number): void { }
    
        gui(gui: GUI): void {
            const general = gui.addFolder('General');
            general.add(SimulationSettings, 'totalMass', SimulationSettings.MIN_TOTAL_MASS, SimulationSettings.MAX_TOTAL_MASS)
                .step(0.1).name('Total Mass').onChange(SimulationSettings.changedParticleSize);
            general.add(SimulationSettings, 'width', SimulationSettings.MIN_WIDTH, SimulationSettings.MAX_WIDTH)
                .step(0.1).name('Width').onChange(SimulationSettings.changedDimensions);
            general.add(SimulationSettings, 'height', SimulationSettings.MIN_HEIGHT, SimulationSettings.MAX_HEIGHT)
                .step(0.1).name('Height').onChange(SimulationSettings.changedDimensions);
            general.add(SimulationSettings, 'resolution', SimulationSettings.MIN_RESOLUTION, SimulationSettings.MAX_RESOLUTION)
                .step(1).name('Resolution').onChange(SimulationSettings.generateTextile);
            general.open();
    
            const extForce = general.addFolder('External Force');
            extForce.add(SimulationSettings.externalForce, 'x',).step(0.01);
            extForce.add(SimulationSettings.externalForce, 'y',).step(0.01);
            extForce.add(SimulationSettings.externalForce, 'z',).step(0.01);
            extForce.open();
    
            const particles = gui.addFolder('Particles');
            particles.add(SimulationSettings, 'switchParticlePhysics').name('Switch Particle Physics');
            particles.addColor(SimulationSettings, 'pColorDefault').name('Default').onChange(SimulationSettings.changedParticleColor);
            particles.addColor(SimulationSettings, 'pColorNoPhysix').name('No Phyisx').onChange(SimulationSettings.changedParticleColor);
            particles.open();
    
            const springs = gui.addFolder('Springs');
            springs.add(SimulationSettings.sConstants, 'structural', SimulationSettings.MIN_CONSTANT, SimulationSettings.MAX_CONSTANT)
                .step(0.1).name('Structural');
            springs.add(SimulationSettings.sConstants, 'shear', SimulationSettings.MIN_CONSTANT, SimulationSettings.MAX_CONSTANT)
                .step(0.1).name('Shear');
            springs.add(SimulationSettings.sConstants, 'bend', SimulationSettings.MIN_CONSTANT, SimulationSettings.MAX_CONSTANT)
                .step(0.1).name('Bend');
            springs.addColor(SimulationSettings, 'sColorStructural').name('Structural').onChange(SimulationSettings.changedSpringColor);
            springs.addColor(SimulationSettings, 'sColorShear').name('Shear').onChange(SimulationSettings.changedSpringColor);
            springs.addColor(SimulationSettings, 'sColorBend').name('Bend').onChange(SimulationSettings.changedSpringColor);
            springs.open();
        }
    }
    
    export { SimulationSettings };