Processing Frames drop over time, Array of multiple 1000s of objects

I am trying to write a line editor for the game “BeamNG”. It takes in a JSON file and lets you edit waypoints (values) of that JSON. If I start the program it works fine, but as soon as I zoom in the Framerate begins to decline, and never recovers no matter what I do.

I’ve tried using different modes like P2D, but none of them help the framerate, I guess this is due to me running the calculations on the CPU and never using the added functunality of P2D.

I cant really pinpoint where this is coming from, so I’ll need to dump my entire project here, sorry…

//Scaling and translating vars
float Scale=1;
float transX,transY;
float transSpeed=1;
//File stuff
String file;
String filepath;
//Setup and stuff
void settings(){
  size(1080,720);
  noSmooth();
  selectInput("Select line file","fileSelected");
  while (filepath == null)  delay(100);
  json = loadJSONObject(filepath);
  recording = json.getJSONObject("recording");
  values = recording.getJSONArray("path");
  declare();
}

void setup () {
  background(0);
  frameRate(30);
  initKeys();
}


void draw () {
  CheckKeys();
  //clearing
  background(0);
  //Static Content
  fill(255);
  text(filepath,50,50);
  text("framerate:  "+frameRate,50,80);
  if (debug==true) {
  text((mouseX/Scale)-transX,400,400);
  text((mouseY/Scale)-transY,500,400);
  }
  //translation and Scaling
  scale(Scale);
  translate(transX,transY);
  //Content
  displayContent();
}


void fileSelected(File selection){
  file=selection.getName();
  println(file);
  filepath=selection.getAbsolutePath();
}

JSONObject direction;
JSONObject json;
JSONObject recording;
JSONArray values;
waypoint[] waypoints;
ArrayList<Float> waypointsX = new ArrayList<Float>();
ArrayList<Float> waypointsY = new ArrayList<Float>();
ArrayList<Float> waypointsZ = new ArrayList<Float>();
ArrayList<Float> waypointsT = new ArrayList<Float>();
void declare(){
  int length = values.size();
  for (int i=0;i<length;i++){
      JSONObject waypoint=values.getJSONObject(i);
      waypointsX.add(waypoint.getFloat("x"));
      waypointsY.add(-waypoint.getFloat("y"));
      waypointsZ.add(waypoint.getFloat("z"));
      waypointsT.add(waypoint.getFloat("t"));
  //Declaring waypoints  
  waypoints= new waypoint[values.size()];
  }
  direction=values.getJSONObject(0);
  //println(direction);
  for (int i=1;i!=values.size();i++) {
  waypoints[i] = new waypoint(i);
    }
  //setting starting coords
  transX=540+waypointsX.get(2);
  transY=360+waypointsY.get(2);
  println(waypointsX.size());
}

  
  
void displayContent() {
    for (int i=1;i<waypointsX.size();i++) {
    waypoints[i].display(waypointsX.get(i),waypointsY.get(i),waypointsT.get(i)); 
  }
}

String ExportPath;
void export(){
  for (int i=1;i<values.size();i++) {
      JSONObject waypoint= new JSONObject();
      waypoint.setFloat("x",waypointsX.get(i));
      waypoint.setFloat("y",-waypointsY.get(i));
      waypoint.setFloat("z",waypointsZ.get(i));
      waypoint.setFloat("t",waypointsT.get(i));
      values.setJSONObject(i,waypoint);
    }
  values.setJSONObject(0,direction);
  recording.setJSONArray("path",values);
  json.setString("vehicle","super");
  json.setJSONObject("recording",recording);
  ExportPath=filepath;
  ExportPath= ExportPath.replace(".track.json","-EDITED");
  println(ExportPath);
  saveJSONObject(json,ExportPath+".track.json");
}

JSONObject keysPressed= new JSONObject();
void keyPressed(){
    //key logging
    keysPressed.setBoolean(Character.toString(key),true);
    //translation Speed
    if (keyPressed&&key=='x') {
      transSpeed=transSpeed+transSpeed*0.9;
    }
     if (keyPressed&&key=='c') {
      transSpeed=transSpeed-transSpeed*0.9;
    }  
  //debug
    if (key=='l' &&! debug==true) {
      debug=true;
    }
      else {
        debug=false;
    }
    //saving
    if (key=='o') {
    export();
  }
}

////!!!! LIST OF ALL PRESSED KEYS!
//// DO FUNCCTIONS IF KEY IS ON LIST


void CheckKeys(){
  if (keysPressed.getBoolean("q")) {
      Scale=Scale+Scale*0.02;
      translateIn();
  }
  //Scrolling out
  if (keysPressed.getBoolean("e")) {
    Scale=Scale-Scale*0.02;
    translateOut();
  }
  //translate right
    if (keysPressed.getBoolean("a")) {
    transX=transX+(5*((1/Scale)*transSpeed));
  }
  //translate left
    if (keysPressed.getBoolean("d")) {
    transX=transX-(5*((1/Scale)*transSpeed));
    }
  //translate down
    if (keysPressed.getBoolean("s")) {
    transY=transY-(5*((1/Scale)*transSpeed));
  }
  //translate up
    if (keysPressed.getBoolean("w")) {
    transY=transY+(5*((1/Scale)*transSpeed));
  }
}

void keyReleased(){
  keysPressed.setBoolean(Character.toString(key),false);
}

void translateIn(){
  transX=transX-(5*((1/Scale)*2));
  transY=transY-(5*((1/Scale)*1.8));
}
void translateOut(){
  transX=transX+(5*((1/Scale)*2));
  transY=transY+(5*((1/Scale)*1.9));
}


void initKeys(){
  keysPressed.setBoolean("q",false);
  keysPressed.setBoolean("e",false);
  keysPressed.setBoolean("w",false);
  keysPressed.setBoolean("s",false);
  keysPressed.setBoolean("a",false);
  keysPressed.setBoolean("d",false);
}

ArrayList<Float> Speed=new ArrayList<Float>();
ArrayList Distance;
float CircSize;
float StrokeWidth;
float StrokeWidthLine;
Boolean Selected = false;
float MaxSpeed=0;
float MinSpeed=10000;
color interpolate;
class waypoint {
  boolean dragging = false;
  float x;
  float y;
  float t;
  int indexNumber;
  waypoint(int idx) {
    indexNumber=idx;
     Speed.add(0,1.1);
    }
  
  void init(){
    for (int i=0;i<waypointsX.size();i++) {
      Speed.add(i,1.0);
    }
  }
  
  
  void display(float xt,float yt,float tt){
    if (!Setup) { 
      Speed.add(indexNumber,1.1);
      if (indexNumber==waypointsX.size()){
        Setup=true;
      }
    }
    if (Scale<3) {
      CircSize=5;
      StrokeWidth=0.2;
      StrokeWidthLine=2;
    }
    else {
      CircSize=15/Scale;
      StrokeWidth=1.5/Scale;
      StrokeWidthLine=6/Scale;
    }
    
    //vars
    x=xt;
    y=yt;
    t=tt;
    float nx=xt;
    float ny=yt;
    float nt=tt;
    float distance;
    
    //assigning next waypoint number
    if (indexNumber+2 < waypointsX.size() ){
    nx=waypointsX.get(indexNumber+1);
    ny=waypointsY.get(indexNumber+1);
    nt=waypointsT.get(indexNumber+1);
    }
    
    
    //Dragging
    if (dragging) {
      waypointsX.set(indexNumber,(mouseX/Scale)-transX);
      waypointsY.set(indexNumber,(mouseY/Scale)-transY);
    }
    //Speed
    distance=dist(x,y,nx,ny);
    Speed.set(indexNumber,distance/(nt-t));
    if(indexNumber==1){
      MaxSpeed=0;
      MinSpeed=10000;
    }
    if (Speed.get(indexNumber)>MaxSpeed){
      MaxSpeed=Speed.get(indexNumber);
    }
    if (Speed.get(indexNumber)<MinSpeed){
      MinSpeed=Speed.get(indexNumber);
    }
    //Drawing
    getColor(Speed.get(indexNumber));
    stroke(interpolate);
    strokeWeight(StrokeWidthLine);
    line(x,y,nx,ny);
    strokeWeight(StrokeWidth);
    stroke(0,100,265);
    fill(0,255,0,0);
    ellipseMode(CENTER); 
    ellipse(x,y,CircSize,CircSize);
  }
  void check (){
  if (ClickedCirc(x,y)) {
    if (dragging == false && Selected == false) {
      dragging=true;
      Selected=true;
    }  else {
        if (dragging==true && Selected==true){ 
          Selected=false;
          BreakPathLoop=true;
        }
        dragging=false;
        }
      }
    }
  }
  
  
void getColor(float s){
  //println(MaxSpeed,MinSpeed);
  float fraction=1/(MaxSpeed-MinSpeed);
  color red =color(265,0,0);
  color green =color(0,265,0);
  interpolate=lerpColor(green,red,fraction*s);
}

void mousePressed(){
  for (int i = 1;i<waypointsX.size();i++){
    waypoints[i].check();
    if (BreakPathLoop==true) {
      BreakPathLoop=false;
      break;
    }
  }



}


//boolean for click testing

boolean ClickedCirc(float x,float y){
  if (dist((mouseX/Scale)-transX,(mouseY/Scale)-transY,x,y) < CircSize/2){
    return true;
  }  else {
    return false;
    }
}

Here’s a short .json, actual lines are much longer than that at up to 30000 waypoints(yeah, I understand why that’d be lagging)

{
"vehicle":"sbr",
"recording":{
  "path":[
    {
      "t":0,
      "x":0.664007,
      "dir":{
        "y":-0.999998,
        "x":0.00177055,
        "z":0.000748247
      },
      "y":-0.65255,
      "z":0.592842,
      "up":{
        "y":0.000634675,
        "x":0.0031207,
        "z":0.999995
      },
    ...
    {
      "y":-35.9782,
      "x":-7.72883,
      "z":0.593799,
      "t":13.054
    }
  ]
},
"levelName":"smallgrid"
}

Do you see any possible causes of this issue, or do you have any optimization ideas?

1 Like

Can you explain what you mean by “zoom in”? Your sketch code doesn’t contain a function/method zoom.