【问题标题】:Processing P3D sketch not working in Javascript mode处理 P3D 草图在 Javascript 模式下不起作用
【发布时间】:2014-04-01 17:46:22
【问题描述】:

我正在尝试将我在处理 [Java 模式] 中构建的项目转换为能够在网络上查看。该项目利用 P3D 渲染来显示可以旋转的 3D 世界,也可以更改 3 个数据集(.tsv 文件)映射三年内发生的地震的位置和大小。以下代码在 Java 中运行时运行良好,但当我在 Javascript 模式下运行时,我只得到一个空白的灰色屏幕。将草图嵌入画布的 HTML 是正确的并且没有错误,所以我确信代码中的某些内容与 Javascript 不兼容。有没有办法将 PDE 作为 java 运行而不必使用 Processing.js,否则在与 processing.js 的兼容性方面代码有什么明显错误吗?

如果有帮助,这里是link to the sketch that is not working

非常感谢任何关于我应该做什么的建议。谢谢

float dial = 0.0;
FloatTable data;
FloatTable data2;
float dataMin, dataMax;
int rowCount;
int currentColumn = 0;
int columnCount;

int yearMin, yearMax;
int[] years;

int yearInterval = 10;
int volumeInterval = 10;
int volumeIntervalMinor=5;

PImage bg;
PImage texmap;
PFont font;
PImage img, img2;
PImage imgTitle;

int sDetail = 35;  // Sphere detail setting
float rotationX = 0;
float rotationY = 0;
float velocityX = 0;
float velocityY = 0;
float globeRadius = 750;
float pushBack = 0;

float[] cx, cz, sphereX, sphereY, sphereZ;
float sinLUT[];
float cosLUT[];
float SINCOS_PRECISION = 0.5;
int SINCOS_LENGTH = int(360.0 / SINCOS_PRECISION);

void setup() {
size(1300,1000, P3D);  
textSize(100);
texmap = loadImage("img/world32k.jpg");   
initializeSphere(sDetail);
setupstuff("2011.tsv");
}

void draw() {    

background(0);    
// drawTitle(); 
drawMain();
renderGlobe(); 
drawDial();

}
void setupstuff(String filename){
data = new FloatTable(filename);
rowCount=data.getRowCount();
columnCount = data.getColumnCount();
years = int(data.getRowNames());
yearMin = years[0];
yearMax = years[years.length - 1];
font = loadFont("Univers-Bold-12.vlw");
dataMin = 0;
dataMax = ceil( data.getTableMax()/volumeInterval)*volumeInterval;
img = loadImage("img/dialface.jpg");
img2 = loadImage("img/dial.png");
imgTitle = loadImage("Title.png");
imageMode(CENTER);
} 
void renderGlobe() {
pushMatrix();
translate(width * 0.33, height * 0.4, pushBack);
// pushMatrix();
noFill();
stroke(255,200);
strokeWeight(2);
smooth();
//popMatrix();
pointLight(201, 252, 276, width * 0.3, height * 0.2, 660);   
pushMatrix();
rotateX( radians(-rotationX) );  
rotateY( radians(180 - rotationY) );
fill(200);
noStroke();
textureMode(IMAGE);  
texturedSphere(globeRadius, texmap);
popMatrix();
drawDots(0);
popMatrix();
rotationX += velocityX;
rotationY += velocityY;
velocityX *= 0.95;
velocityY *= 0.95;

// Implements mouse control (interaction will be inverse when sphere is  upside down)
if(mousePressed){
velocityX += (mouseY-pmouseY) * 0.01;
velocityY -= (mouseX-pmouseX) * 0.01;
}
}

void initializeSphere(int res)
{
sinLUT = new float[SINCOS_LENGTH];
cosLUT = new float[SINCOS_LENGTH];

for (int i = 0; i < SINCOS_LENGTH; i++) {
sinLUT[i] = (float) Math.sin(i * DEG_TO_RAD * SINCOS_PRECISION);
cosLUT[i] = (float) Math.cos(i * DEG_TO_RAD * SINCOS_PRECISION);
}

float delta = (float)SINCOS_LENGTH/res;
float[] cx = new float[res];
float[] cz = new float[res];

// Calc unit circle in XZ plane
for (int i = 0; i < res; i++) {
cx[i] = -cosLUT[(int) (i*delta) % SINCOS_LENGTH];
cz[i] = sinLUT[(int) (i*delta) % SINCOS_LENGTH];
}

// Computing vertexlist vertexlist starts at south pole
int vertCount = res * (res-1) + 2;
int currVert = 0;

// Re-init arrays to store vertices
sphereX = new float[vertCount];
sphereY = new float[vertCount];
sphereZ = new float[vertCount];
float angle_step = (SINCOS_LENGTH*0.5f)/res;
float angle = angle_step;

// Step along Y axis
for (int i = 1; i < res; i++) {
float curradius = sinLUT[(int) angle % SINCOS_LENGTH];
float currY = -cosLUT[(int) angle % SINCOS_LENGTH];
for (int j = 0; j < res; j++) {
sphereX[currVert] = cx[j] * curradius;
sphereY[currVert] = currY;
sphereZ[currVert++] = cz[j] * curradius;
}
angle += angle_step;
}
sDetail = res;
}

// Draw texture sphere
void texturedSphere(float r, PImage t) {
int v1,v11,v2;
r = (r + 240 ) * 0.33;
beginShape(TRIANGLE_STRIP);
texture(t);
float iu=(float)(t.width-1)/(sDetail);
float iv=(float)(t.height-1)/(sDetail);
float u=0,v=iv;
for (int i = 0; i < sDetail; i++) {
vertex(0, -r, 0,u,0);
vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v);
u+=iu;
}
vertex(0, -r, 0,u,0);
vertex(sphereX[0]*r, sphereY[0]*r, sphereZ[0]*r, u, v);
endShape();   

// Middle rings
int voff = 0;
for(int i = 2; i < sDetail; i++) {
v1=v11=voff;
voff += sDetail;
v2=voff;
u=0;
beginShape(TRIANGLE_STRIP);
texture(t);
for (int j = 0; j < sDetail; j++) {
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv);
u+=iu;
}

// Close each ring
v1=v11;
v2=voff;
vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v);
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v+iv);
endShape();
v+=iv;
}
u=0;

// Add the northern cap
beginShape(TRIANGLE_STRIP);
texture(t);
for (int i = 0; i < sDetail; i++) {
v2 = voff + i;
vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v);
vertex(0, r, 0,u,v+iv);    
u+=iu;
}
vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v);
endShape();

}
//draw dot
void drawDots(float r){
r = (r + 240 ) * 0.33;
blendMode(ADD);
stroke(255, 100, 0, 100);
rotateX( radians(-rotationX) );  
rotateY( radians(270 - rotationY) );


for(int row = 0; row<rowCount; row++){  
int col2 = 0;
int col3 = 1;
int col4 = 2;
float latY = data.getFloat(row, col2);
float longX = data.getFloat(row, col3);
float ricter = data.getFloat(row, col4);
pushMatrix();
rotateX(radians(-latY));
rotateY(radians(longX));
translate(0,0,r+250);
ellipse(0,0,ricter*ricter*ricter/20,ricter*ricter*ricter/20);
popMatrix(); 
println(latY); 
}
rotationX += velocityX;
rotationY += velocityY;
velocityX *= 0.95;
velocityY *= 0.95;
}
void drawDial(){
translate(width-250, height-250);
image(img, -9/2, 53/2, 830/2,626/2 );
if(keyPressed){
if (key == '1') {
dial = radians( 0 );
setupstuff("2011.tsv");
}
if (key == '2') {
dial = radians( 120 );
setupstuff("2012.tsv");
}
if (key == '3') {
dial = radians( 240 );
setupstuff("2010.tsv");
}
}

rotate(dial);
image(img2, 103/2, -65/2, 314/2, 400/2);
}
void drawMain(){
image(imgTitle, width-320, 170);
}
void drawTitle(){
pushMatrix();
fill(255,255, 255);
translate(width-300, 120);
textFont(font, 32);
text("Earthquakes", 10, 50);
popMatrix();
}

class FloatTable {
int rowCount;
int columnCount;
float[][] data;
String[] rowNames;
String[] columnNames;


FloatTable(String filename) {
String[] rows = loadStrings(filename);

String[] columns = split(rows[0], TAB);
columnNames = subset(columns, 1); // upper-left corner ignored
scrubQuotes(columnNames);
columnCount = columnNames.length;

rowNames = new String[rows.length-1];
data = new float[rows.length-1][];

// start reading at row 1, because the first row was only the column headers
for (int i = 1; i < rows.length; i++) {
  if (trim(rows[i]).length() == 0) {
    continue; // skip empty rows
  }
  if (rows[i].startsWith("#")) {
    continue;  // skip comment lines
  }

  // split the row on the tabs
  String[] pieces = split(rows[i], TAB);
  scrubQuotes(pieces);

  // copy row title
  rowNames[rowCount] = pieces[0];
  // copy data into the table starting at pieces[1]
  data[rowCount] = parseFloat(subset(pieces, 1));

  // increment the number of valid rows found so far
  rowCount++;      
}
// resize the 'data' array as necessary
data = (float[][]) subset(data, 0, rowCount);
}

void scrubQuotes(String[] array) {
for (int i = 0; i < array.length; i++) {
  if (array[i].length() > 2) {
    // remove quotes at start and end, if present
    if (array[i].startsWith("\"") && array[i].endsWith("\"")) {
      array[i] = array[i].substring(1, array[i].length() - 1);
    }
  }
  // make double quotes into single quotes
  array[i] = array[i].replaceAll("\"\"", "\"");
}
}


int getRowCount() {
return rowCount;
}


String getRowName(int rowIndex) {
return rowNames[rowIndex];
}
String[] getRowNames() {
return rowNames;
}
int getRowIndex(String name) {
for (int i = 0; i < rowCount; i++) {
  if (rowNames[i].equals(name)) {
    return i;
  }
}
//println("No row named '" + name + "' was found");
return -1;
}



int getColumnCount() {
return columnCount;
}

String getColumnName(int colIndex) {
return columnNames[colIndex];
}

String[] getColumnNames() {
return columnNames;
}

float getFloat(int rowIndex, int col) {

if ((rowIndex < 0) || (rowIndex >= data.length)) {
  throw new RuntimeException("There is no row " + rowIndex);
}
if ((col < 0) || (col >= data[rowIndex].length)) {
  throw new RuntimeException("Row " + rowIndex + " does not have a column " + col);
}
return data[rowIndex][col];
}

boolean isValid(int row, int col) {
if (row < 0) return false;
if (row >= rowCount) return false;
//if (col >= columnCount) return false;
if (col >= data[row].length) return false;
if (col < 0) return false;
return !Float.isNaN(data[row][col]);
}


float getColumnMin(int col) {
float m = Float.MAX_VALUE;
for (int row = 0; row < rowCount; row++) {
  if (isValid(row, col)) {
    if (data[row][col] < m) {
      m = data[row][col];
    }
  }
}
return m;
}


float getColumnMax(int col) {
float m = -Float.MAX_VALUE;
for (int row = 0; row < rowCount; row++) {
  if (isValid(row, col)) {
    if (data[row][col] > m) {
      m = data[row][col];
    }
  }
}
return m;
}


float getRowMin(int row) {
float m = Float.MAX_VALUE;
for (int col = 0; col < columnCount; col++) {
  if (isValid(row, col)) {
    if (data[row][col] < m) {
      m = data[row][col];
    }
  }
}
return m;
} 


float getRowMax(int row) {
float m = -Float.MAX_VALUE;
for (int col = 0; col < columnCount; col++) {
  if (isValid(row, col)) {
    if (data[row][col] > m) {
      m = data[row][col];
    }
  }
}
return m;
}


float getTableMin() {
float m = Float.MAX_VALUE;
for (int row = 0; row < rowCount; row++) {
  for (int col = 0; col < columnCount; col++) {
    if (isValid(row, col)) {
      if (data[row][col] < m) {
        m = data[row][col];
      }
    }
  }
}
return m;
}  


float getTableMax() {
float m = -Float.MAX_VALUE;
for (int row = 0; row < rowCount; row++) {
  for (int col = 0; col < columnCount; col++) {
    if (isValid(row, col)) {
      if (data[row][col] > m) {
        m = data[row][col];
      }
    }
  }
}
return m;
}
}

【问题讨论】:

  • 好的,页面加载时控制台报错未捕获异常:Processing.js: Unable to execute pjs sketch: ReferenceError: Float is not defined (10223 out of range 10203)
  • 您是否有存储所有数据文件的存储库?我什至无法运行此草图,因为您有大量图像文件和字体文件,这对我来说很容易解决,但我无法生成图像文件。发布指向您的数据文件夹存储库的链接,以便我可以在我的计算机上下载并测试它,以便能够告诉您发生了什么。在等待您发布链接的同时,我将发布一个包含可能解决您问题的修复程序的答案。
  • @Nicolas Carlo 这是一个link to the a zip file,包含在 Java 模式下运行所需的一切。谢谢
  • DOofficial -- 请将控制台错误添加到问题中。

标签: java javascript webgl processing processing.js


【解决方案1】:

更新

您关于Float 的错误可能与此行有关:

return !Float.isNaN(data[row][col]);

Javascript 无法识别Float,这是一个 Java 构造,并未在 Processing 中完全实现。您需要找到其他内容进行比较,例如:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN

类似下面的所有语句

float m = Float.MAX_VALUE;

不适用于 ProcessingJS。你可能想看看:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity

ProcessingJS 非常难以调试,因此您需要确保避免所有仅是 Java 且未在 Processing 中完全实现的东西。您还需要避免变量名冲突。阅读以下内容以了解其他可能出现的问题:http://processingjs.org/articles/p5QuickStart.html#thingstoknowusingpjs

以下方法也没有右大括号:

float getTableMin() {
    float m = Float.MAX_VALUE;
    for (int row = 0; row < rowCount; row++) {
      for (int col = 0; col < columnCount; col++) {
        if (isValid(row, col)) {
          if (data[row][col] < m) {
            m = data[row][col];
          }
        }
      }
    }
    return m;

通过像这样添加右大括号来解决这个问题:

float getTableMin() {
    float m = Float.MAX_VALUE;
    for (int row = 0; row < rowCount; row++) {
      for (int col = 0; col < columnCount; col++) {
        if (isValid(row, col)) {
          if (data[row][col] < m) {
            m = data[row][col];
          }
        }
      }
    }
    return m;
}  

这就是为什么正确格式化代码会有所帮助的原因。在您的处理 IDE 中,选择您的代码,然后按 Ctrl-t,这应该会自动将您的代码格式化为更易于阅读的内容。

顺便说一句,如果没有此修复,您的代码甚至无法在 Java 模式下运行。它将为相关方法抛出unexpected token: float 异常。

更新 2

为了能够摆脱您的Float相关代码,您可以更改以下行

return !Float.isNaN(data[row][col]);

return isNaN(data[row][col]);

您可以将Float.MAX_VALUE; 的所有实例更改为Number.MAX_VALUE;

将所有实例更改为 Javascript 友好代码后,我也收到了您遇到的错误。我会尝试看看我是否能弄清楚并更新答案。

【讨论】:

  • 我查看了原始草图,发现缺少的括号在那里。它一定是在格式化以在此站点上发布时以某种方式丢失了,或者我删除了很多我删除的评论行(我已经更新了原始帖子)。无论如何,不​​错的收获,感谢您发布的链接。我也认为是 javascript 将 Float 和 float 视为相同。我将查看您提供的链接,并让您知道是否有任何进展。再次感谢。 PS 我还在您之前的评论中发布了一个 zip 文件的链接,如果有帮助,您可以在其中下载完整的草图文件夹
  • 我不确定如何从链接中实现更改,但我已删除 Float 的实例并用静态数字替换它们,这在浏览器中引发了一些错误,但绘制了草图和标题img:确认这是错误的来源。进一步调试后,我现在得到的唯一错误是: IndexSizeError: Index or size is negative or greater than the allowed amount ....drawImage(pimage.sourceImg, 0, 0, pimage.width, pimage.height, 0, 0, cvs.width,...这是由于静态数据超出表格还是在地球的渲染范围内?
  • @DOOfficial 我去看看。就像我之前说的,ProcessingJS 非常难以调试,所以我可能会空手而归。我们拭目以待。
  • @DOOfficial 查看我的更新答案,了解如何在代码中使用 Javascript 结构来替换与 Floats 相关的所有内容。
  • 感谢它的魅力。经过进一步调试,到目前为止,我已经在 Firefox 中运行它(还有很多工作要做)。如果您有时间look at it again,您能告诉我为什么图像加载如此奇怪吗?即:如果标题和导航正确加载,则地球无法加载,并且如果地球加载标题和导航似乎继承了地球的大小。我是否没有正确地从矩阵中推出和弹出?您可能需要多次重新加载页面才能看到我在说什么。
【解决方案2】:

使用以下代码代替 fullscreen():


size(window.innerWidth, window.innerHeight, P3D);

注意: 不适用于 IE。 如果是 IE:

void setup() {
    if (window.innerWidth) {
        wW = window.innerWidth;
        wH = window.innerHeight;
    } else {
        var cW = document.body.offsetWidth;
        var cH = document.body.offsetHeight;
        window.resizeTo(500,500);
        var barsW = 500 - document.body.offsetWidth;
        var barsH = 500 - document.body.offsetHeight;
        wW = barsW + cW;
        wH = barsH + cH;
        window.resizeTo(wW,wH);
    }
    size(wW,wH,P3D);
}

【讨论】:

    猜你喜欢
    • 2021-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多