Commit af3d6642 authored by amandaghassaei's avatar amandaghassaei

added actuation to quaternion calc

parent 68eeddfa
......@@ -62,7 +62,8 @@ define(['underscore', 'backbone', 'threeModel', 'lattice', 'plist', 'emWire', 'G
this.compositeKs = new Float32Array(textureSize*8);
this.compositeDs = new Float32Array(textureSize*8);
this.wires = new Int16Array(textureSize*4);//also stores actuator mask as -1
//todo int array
this.wires = new Float32Array(textureSize*4);//also stores actuator mask as -1
var wires = this.get("wires");
this.resetWiresMetaTexture(wires);
......@@ -212,6 +213,8 @@ define(['underscore', 'backbone', 'threeModel', 'lattice', 'plist', 'emWire', 'G
gpuMath.initTextureFromData("u_compositeKs", textureDim*2, textureDim, "FLOAT", this.compositeKs);
gpuMath.initTextureFromData("u_compositeDs", textureDim*2, textureDim, "FLOAT", this.compositeDs);
gpuMath.initTextureFromData("u_originalPosition", textureDim, textureDim, "FLOAT", this.originalPosition);
gpuMath.initTextureFromData("u_wires", textureDim, textureDim, "FLOAT", this.wires);//todo byte
gpuMath.initTextureFromData("u_wiresMeta", 1, this.wiresMeta.length/4, "FLOAT", this.wiresMeta);
gpuMath.createProgram("quaternionCalc", vertexShader, quaternionCalcShader);
gpuMath.setUniformForProgram("quaternionCalc", "u_lastTranslation", 0, "1i");
......@@ -220,8 +223,12 @@ define(['underscore', 'backbone', 'threeModel', 'lattice', 'plist', 'emWire', 'G
gpuMath.setUniformForProgram("quaternionCalc", "u_neighborsXMapping", 3, "1i");
gpuMath.setUniformForProgram("quaternionCalc", "u_neighborsYMapping", 4, "1i");
gpuMath.setUniformForProgram("quaternionCalc", "u_compositeKs", 5, "1i");
gpuMath.setUniformForProgram("quaternionCalc", "u_wires", 6, "1i");
gpuMath.setUniformForProgram("quaternionCalc", "u_wiresMeta", 7, "1i");
gpuMath.setUniformForProgram("quaternionCalc", "u_textureDim", [textureDim, textureDim], "2f");
gpuMath.setUniformForProgram("quaternionCalc", "u_latticePitch", [latticePitch.x, latticePitch.y, latticePitch.z], "3f");
gpuMath.setUniformForProgram("quaternionCalc", "u_wiresMetaLength", this.wiresMeta.length/4, "1f");
gpuMath.setUniformForProgram("quaternionCalc", "u_time", 0, "1f");
gpuMath.createProgram("velocityCalc", vertexShader, velocityCalcShader);
gpuMath.setUniformForProgram("velocityCalc", "u_lastVelocity", 0, "1i");
......@@ -450,69 +457,69 @@ define(['underscore', 'backbone', 'threeModel', 'lattice', 'plist', 'emWire', 'G
iter: function(dt, time, gravity, shouldRender){
//gpuMath.step("quaternionCalc", ["u_lastTranslation", "u_lastQuaternion", "u_fixed", "u_neighborsXMapping",
// "u_neighborsYMapping", "u_compositeKs"], "u_quaternion");
//gpuMath.step("velocityCalc", ["u_lastVelocity", "u_lastTranslation", "u_mass", "u_fixed", "u_neighborsXMapping",
// "u_neighborsYMapping", "u_compositeKs", "u_compositeDs", "u_originalPosition", "u_lastQuaternion"],
// "u_velocity");
//gpuMath.step("positionCalc", ["u_velocity", "u_lastTranslation", "u_fixed"], "u_translation");
//
//if (shouldRender) {
// var textureSize = this.textureSize[0]*this.textureSize[1];
//
// //get position
// var vectorLength = 3;
// gpuMath.setProgram("packToBytes");
// gpuMath.setUniformForProgram("packToBytes", "u_vectorLength", vectorLength, "1f");
// gpuMath.setSize(this.textureSize[0]*vectorLength, this.textureSize[1]);
// gpuMath.step("packToBytes", ["u_translation"], "outputPositionBytes");
// var pixels = new Uint8Array(textureSize * 4*vectorLength);
// if (gpuMath.readyToRead()) {
// gpuMath.readPixels(0, 0, this.textureSize[0] * vectorLength, this.textureSize[1], pixels);
// var parsedPixels = new Float32Array(pixels.buffer);
// var cells = lattice.getCells();
// var multiplier = 1 / (plist.allUnitTypes[lattice.getUnits()].multiplier);
// for (var i = 0; i < textureSize; i++) {
// var rgbaIndex = 4 * i;
// if (this.fixed[rgbaIndex] < 0) continue;//no more cells
// var index = [this.cellsArrayMapping[rgbaIndex], this.cellsArrayMapping[rgbaIndex + 1], this.cellsArrayMapping[rgbaIndex + 2]];
// var parsePixelsIndex = vectorLength * i;
// var translation = [parsedPixels[parsePixelsIndex], parsedPixels[parsePixelsIndex + 1], parsedPixels[parsePixelsIndex + 2]];
// var position = [this.originalPosition[rgbaIndex], this.originalPosition[rgbaIndex + 1], this.originalPosition[rgbaIndex + 2]];
// position[0] += multiplier * translation[0];
// position[1] += multiplier * translation[1];
// position[2] += multiplier * translation[2];
// cells[index[0]][index[1]][index[2]].object3D.position.set(position[0], position[1], position[2]);
// }
// }
//
// vectorLength = 4;
// gpuMath.setUniformForProgram("packToBytes", "u_vectorLength", vectorLength, "1f");
// gpuMath.setSize(this.textureSize[0]*vectorLength, this.textureSize[1]);
// gpuMath.step("packToBytes", ["u_quaternion"], "outputQuaternionBytes");
// pixels = new Uint8Array(textureSize * 4*vectorLength);
// if (gpuMath.readyToRead()) {
// gpuMath.readPixels(0, 0, this.textureSize[0] * vectorLength, this.textureSize[1], pixels);
// parsedPixels = new Float32Array(pixels.buffer);
// for (var i = 0; i < textureSize; i++) {
// var rgbaIndex = 4 * i;
// if (this.fixed[rgbaIndex] < 0) break;//no more cells
// var index = [this.cellsArrayMapping[rgbaIndex], this.cellsArrayMapping[rgbaIndex + 1], this.cellsArrayMapping[rgbaIndex + 2]];
// var parsePixelsIndex = vectorLength * i;
// var quaternion = [parsedPixels[parsePixelsIndex], parsedPixels[parsePixelsIndex + 1], parsedPixels[parsePixelsIndex + 2], parsedPixels[parsePixelsIndex + 3]];
// //console.log(quaternion);
// var rotation = this._eulerFromQuaternion(quaternion);
// cells[index[0]][index[1]][index[2]].object3D.rotation.set(rotation[0], rotation[1], rotation[2]);
// }
// }
//
// gpuMath.setSize(this.textureSize[0], this.textureSize[1]);
//}
//
//gpuMath.swapTextures("u_velocity", "u_lastVelocity");
//gpuMath.swapTextures("u_translation", "u_lastTranslation");
//gpuMath.swapTextures("u_quaternion", "u_lastQuaternion");
//return;
gpuMath.step("quaternionCalc", ["u_lastTranslation", "u_lastQuaternion", "u_fixed", "u_neighborsXMapping",
"u_neighborsYMapping", "u_compositeKs"], "u_quaternion", "u_wires", "u_wiresMeta", time);
gpuMath.step("velocityCalc", ["u_lastVelocity", "u_lastTranslation", "u_mass", "u_fixed", "u_neighborsXMapping",
"u_neighborsYMapping", "u_compositeKs", "u_compositeDs", "u_originalPosition", "u_lastQuaternion"],
"u_velocity");
gpuMath.step("positionCalc", ["u_velocity", "u_lastTranslation", "u_fixed"], "u_translation");
if (shouldRender) {
var textureSize = this.textureSize[0]*this.textureSize[1];
//get position
var vectorLength = 3;
gpuMath.setProgram("packToBytes");
gpuMath.setUniformForProgram("packToBytes", "u_vectorLength", vectorLength, "1f");
gpuMath.setSize(this.textureSize[0]*vectorLength, this.textureSize[1]);
gpuMath.step("packToBytes", ["u_translation"], "outputPositionBytes");
var pixels = new Uint8Array(textureSize * 4*vectorLength);
if (gpuMath.readyToRead()) {
gpuMath.readPixels(0, 0, this.textureSize[0] * vectorLength, this.textureSize[1], pixels);
var parsedPixels = new Float32Array(pixels.buffer);
var cells = lattice.getCells();
var multiplier = 1 / (plist.allUnitTypes[lattice.getUnits()].multiplier);
for (var i = 0; i < textureSize; i++) {
var rgbaIndex = 4 * i;
if (this.fixed[rgbaIndex] < 0) continue;//no more cells
var index = [this.cellsArrayMapping[rgbaIndex], this.cellsArrayMapping[rgbaIndex + 1], this.cellsArrayMapping[rgbaIndex + 2]];
var parsePixelsIndex = vectorLength * i;
var translation = [parsedPixels[parsePixelsIndex], parsedPixels[parsePixelsIndex + 1], parsedPixels[parsePixelsIndex + 2]];
var position = [this.originalPosition[rgbaIndex], this.originalPosition[rgbaIndex + 1], this.originalPosition[rgbaIndex + 2]];
position[0] += multiplier * translation[0];
position[1] += multiplier * translation[1];
position[2] += multiplier * translation[2];
cells[index[0]][index[1]][index[2]].object3D.position.set(position[0], position[1], position[2]);
}
}
vectorLength = 4;
gpuMath.setUniformForProgram("packToBytes", "u_vectorLength", vectorLength, "1f");
gpuMath.setSize(this.textureSize[0]*vectorLength, this.textureSize[1]);
gpuMath.step("packToBytes", ["u_quaternion"], "outputQuaternionBytes");
pixels = new Uint8Array(textureSize * 4*vectorLength);
if (gpuMath.readyToRead()) {
gpuMath.readPixels(0, 0, this.textureSize[0] * vectorLength, this.textureSize[1], pixels);
parsedPixels = new Float32Array(pixels.buffer);
for (var i = 0; i < textureSize; i++) {
var rgbaIndex = 4 * i;
if (this.fixed[rgbaIndex] < 0) break;//no more cells
var index = [this.cellsArrayMapping[rgbaIndex], this.cellsArrayMapping[rgbaIndex + 1], this.cellsArrayMapping[rgbaIndex + 2]];
var parsePixelsIndex = vectorLength * i;
var quaternion = [parsedPixels[parsePixelsIndex], parsedPixels[parsePixelsIndex + 1], parsedPixels[parsePixelsIndex + 2], parsedPixels[parsePixelsIndex + 3]];
//console.log(quaternion);
var rotation = this._eulerFromQuaternion(quaternion);
cells[index[0]][index[1]][index[2]].object3D.rotation.set(rotation[0], rotation[1], rotation[2]);
}
}
gpuMath.setSize(this.textureSize[0], this.textureSize[1]);
}
gpuMath.swapTextures("u_velocity", "u_lastVelocity");
gpuMath.swapTextures("u_translation", "u_lastTranslation");
gpuMath.swapTextures("u_quaternion", "u_lastQuaternion");
return;
var latticePitch = lattice.getPitch();
latticePitch = [latticePitch.x, latticePitch.y, latticePitch.z];
......
#define M_PI 3.1415926535897932384626433832795
precision mediump float;
uniform vec2 u_textureDim;
uniform vec3 u_latticePitch;
uniform float u_wiresMetaLength;
uniform float u_time;
uniform sampler2D u_lastTranslation;
uniform sampler2D u_fixed;
......@@ -9,6 +13,10 @@ uniform sampler2D u_neighborsXMapping;
uniform sampler2D u_neighborsYMapping;
uniform sampler2D u_lastQuaternion;
uniform sampler2D u_compositeKs;
uniform sampler2D u_wires;
uniform sampler2D u_wiresMeta;
vec3 applyQuaternion(vec3 vector, vec4 quaternion) {
......@@ -129,15 +137,52 @@ float neighborSign(float i){
return 1.0;
}
vec3 neighborOffset(float i){
vec3 neighborOffset(float i, int neighborAxis){
vec3 offset = vec3(0);
int neighborAxis = int(floor(i/2.0+0.001));
if (neighborAxis == 0) offset[0] = neighborSign(i)*u_latticePitch[0];
else if (neighborAxis == 1) offset[1] = neighborSign(i)*u_latticePitch[1];
else if (neighborAxis == 2) offset[2] = neighborSign(i)*u_latticePitch[2];
return offset;
}
int calcNeighborAxis(int i){
return int(floor(float(i)/2.0+0.001));
}
int convertToInt(float num){
return int(floor(num+0.001));
}
float getActuatorVoltage(float wireIndex){
vec2 wireCoord = vec2(0.5, (floor(wireIndex*4.0+0.001)+0.5)/u_wiresMetaLength);
vec4 wireMeta = texture2D(u_wiresMeta, wireCoord);
int type = convertToInt(1.2);
if (type == -1) {
//no signal connected
return 0.0;
}
float frequency = wireMeta[1];
float period = 1.0/frequency;
float phase = wireMeta[2];
float currentPhase = mod(u_time + phase*period, period)/period;
if (type == 0){
return 0.5*sin(2.0*M_PI*currentPhase);
}
if (type == 1){
float pwm = wireMeta[3];
if (currentPhase < pwm) return 0.5;
return -0.5;
}
if (type == 2){
if (wireMeta[3]>0.5) return 0.5-currentPhase;
return currentPhase-0.5;
}
if (type == 3){
if (currentPhase < 0.5) return currentPhase*2.0-0.5;
return 0.5-(currentPhase-0.5)*2.0;
}
return 0.0;
}
void main(){
......@@ -166,9 +211,14 @@ void main(){
vec3 neighborsYMapping = texture2D(u_neighborsYMapping, mappingIndex).xyz;
vec3 compositeKs = texture2D(u_compositeKs, mappingIndex).xyz;
vec4 wiring = texture2D(u_wires, mappingIndex);
bool isActuator = wiring.x < 0.5;//-1
for (int j=0;j<3;j++){
if (neighborsXMapping[j] < 0.0) continue;//no neighbor
int neighborAxis = calcNeighborAxis(j);
vec2 neighborIndex = vec2(neighborsXMapping[j], neighborsYMapping[j]);
neighborIndex.x += 0.5;
neighborIndex.y += 0.5;
......@@ -178,8 +228,32 @@ void main(){
vec4 neighborQuaternion = texture2D(u_lastQuaternion, scaledNeighborIndex);
vec3 neighborEuler = eulerFromQuaternion(neighborQuaternion);
vec3 nominalD = neighborOffset(i*3.0+float(j));
vec3 actuatedD = nominalD;
vec3 nominalD = neighborOffset(i*3.0+float(j), neighborAxis);
vec3 actuatedD = vec3(nominalD[0], nominalD[1], nominalD[2]);
float actuation = 0.0;
if (isActuator){
if (neighborAxis == 0 && wiring[1]>0.1){//>0
actuation += 0.3*getActuatorVoltage(wiring[1]-1.0);
} else if (neighborAxis == 1 && wiring[2]>0.1){
actuation += 0.3*getActuatorVoltage(wiring[2]-1.0);
} else if (neighborAxis == 2 && wiring[3]>0.1){
actuation += 0.3*getActuatorVoltage(wiring[3]-1.0);
}
}
vec4 neighborWiring = texture2D(u_wires, scaledNeighborIndex);
if (neighborWiring[0] < 0.5){
if (neighborWiring[1]>0.1){
actuation += 0.3*getActuatorVoltage(neighborWiring[1]-1.0);
} else if (neighborWiring[2]>0.1){
actuation += 0.3*getActuatorVoltage(neighborWiring[1]-1.0);
} else if (neighborWiring[3]>0.1){
actuation += 0.3*getActuatorVoltage(neighborWiring[1]-1.0);
}
}
if (neighborAxis == 0) actuatedD[0] *= 1.0+actuation;
else if (neighborAxis == 1) actuatedD[1] *= 1.0+actuation;
else if (neighborAxis == 2) actuatedD[2] *= 1.0+actuation;
vec3 D = neighborTranslation-translation+nominalD;
vec3 halfNominalD = actuatedD*0.5;
......
......@@ -95,9 +95,10 @@ define(['glBoilerplate'], function(glBoilerplate){
gl.useProgram(this.programs[programName].program);
};
GPUMath.prototype.step = function(programName, inputTextures, outputTexture){
GPUMath.prototype.step = function(programName, inputTextures, outputTexture, time){
gl.useProgram(this.programs[programName].program);
if (time) this.setUniformForProgram(programName, "u_time", time, "1f");
gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffers[outputTexture]);
for (var i=0;i<inputTextures.length;i++){
gl.activeTexture(gl.TEXTURE0 + i);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment