Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (481)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (548)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Phys2D, profiling and memory leak  (Read 2618 times)
0 Members and 1 Guest are viewing this topic.
Offline Bonbon-Chan

JGO Coder


Medals: 12



« Posted 2007-09-05 14:04:23 »

I was playing around with Lwjgl and Phys2D to learn how it word, and i came across something "strange".

I made an arena with 32 cells inside it that go randomly. The arena is made of line (Phys2D) and the cells are a circle (main body) with several circle inside it (fixed joint to the main body) where i apply force on.

http://bonbonchan.bravehost.com/images/screen.html

After several minutes, there is a dramatical drop of framerate.

I try to find out with the profiler of Netbean where it can come from (i'm not use to it and i don't really know if i understand it all).

http://bonbonchan.bravehost.com/images/profile.html

The first line is with everything.
The second line is with "world.step();" (the Phys2D objet) commented out. And it seems to be the problem.

May be i have misunderstand something in Phys2D or the profiler. If someone can help me to understand.

ps : i have to change of free hosting -_-,
Offline kevglass

JGO Kernel


Medals: 153
Projects: 23
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #1 - Posted 2007-09-05 16:24:41 »

Looks like a leak to me - can you post the test code? I've not had seen memory issues on my demos - but I've not used it for an age.

Is this with the latest build btw, the last bug I remember was an Arbiter leak.

Kev

Offline Bonbon-Chan

JGO Coder


Medals: 12



« Reply #2 - Posted 2007-09-06 07:52:16 »

I'm using "phys2d-250607.jar" (the lastest build i think). By the way lwjgl 1.1.2 and Java 1.6.0_b105.

My code was a mess  Embarrassed, i remake a test code and it is the same :

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
150  
151  
152  
153  
154  
155  
156  
157  
158  
159  
160  
161  
162  
163  
164  
165  
166  
167  
168  
169  
170  
171  
172  
173  
174  
175  
176  
177  
178  
179  
180  
181  
182  
183  
184  
185  
186  
package cellsoccer;

import net.phys2d.raw.Body;
import net.phys2d.raw.BodyList;
import net.phys2d.raw.FixedJoint;
import net.phys2d.raw.World;
import net.phys2d.raw.shapes.Circle;
import net.phys2d.raw.shapes.Line;
import org.lwjgl.LWJGLException;
import org.lwjgl.Sys;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;

public class Test
{  
    public  static final float fullRadius = 4.0f*40.f;
    public  static final float radius = 3.2f;
    public  static final float radius2= 1.8f;
    private static final int FRAMERATE = 30;
    private static final int NBITERATION = 5;
    private static final float DAMPING = 1.0f;
   
    private static final int displayWidth = 640;
    private static final int displayHeight = 480;
   
    private boolean finished;
   
    private World   world;
   
    public static void main(String[] args)
    {
      new Test();
      System.exit(0);
    }
   
    public Test()    
    {
       initlwjgl();
       initworld();
       run();
    }
   
    private void initlwjgl()
    {
      DisplayMode chosenMode = null;
 
       try
       {
         DisplayMode[] modes = Display.getAvailableDisplayModes();
         for (int i=0;i<modes.length;i++)
         {
           if ((modes[i].getWidth() == displayWidth) && (modes[i].getHeight() == displayHeight))
           {
             chosenMode = modes[i];
             break;
           }
         }
       }
       catch (LWJGLException e)
       {    
          Sys.alert("Error", "Unable to determine display modes.");
          System.exit(0);
       }
 
       if (chosenMode == null)
       {
         Sys.alert("Error", "Unable to find appropriate display mode.");
         System.exit(0);
       }
     
       try
       {
         Display.setDisplayMode(chosenMode);
         Display.setTitle("Test Phys2D");
         Display.setFullscreen(false);
         Display.setVSyncEnabled(true);
         Display.create();
       }
       catch (LWJGLException e)
       {    
          Sys.alert("Error", "Cant' create Display");
          System.exit(0);
       }
    }
   
    private void initworld()
    {
      world = new World(new net.phys2d.math.Vector2f(0.0f,0.0f),NBITERATION);
       world.setDamping(DAMPING);
   
       for(int i=0;i<36;i++)
       {
         double a1 = i*Math.PI/18.0;
         double a2 = (i+1)*Math.PI/18.0;
       
         Body b = new Body(
             new Line(fullRadius*(float)Math.cos(a1),fullRadius*(float)Math.sin(a1),
                      fullRadius*(float)Math.cos(a2),fullRadius*(float)Math.sin(a2))
                      , Body.INFINITE_MASS);
     
         b.setUserData(this);
         world.add(b);
       }
    }
 
  private void initCells()
  {
    float x,y;
     
    for(int i=0;i<32;i++)
    {
      x = (float)Math.random()*fullRadius;
      y = (float)Math.random()*fullRadius;
             
      Body body = new Body(new Circle(radius),1.0f);
      body.setPosition(x,y);
      body.setUserData(this);
     
      world.add(body);
     
      for (int j=0;j<8;j++)
      {
        if (Math.random()>0.5)
        {
          double a = j*Math.PI/4.0 + Math.PI/8;
          Body body2 = new Body(new Circle(radius),0.001f);  
          body2.setPosition((float)(radius2*Math.sin(a))+x,(float)(radius2*Math.cos(a))+y);
          body2.setRotation((float)(a));
     
          world.add(body2);
         
          BodyList bodies = world.getBodies();
          for (int k=0;k<bodies.size();k++)
          {
            Body aBody = bodies.get(k);
       
            aBody.addExcludedBody(body2);
            body2.addExcludedBody(aBody);
          }
         
          FixedJoint joint = new FixedJoint(body,body2);
          world.add(joint);
         
          body2.setForce((float)(Math.random()-0.5),(float)(Math.random()-0.5));
        }
      }
    }
  }
   
  private void run()
  {
    int compt = 0;
   
    Display.update();
   
    initCells();
   
    finished = false;
   
    while (!finished)
    {
      Display.update();
 
      if (Display.isCloseRequested())
      {
   finished = true;
      }
     
      logic();
      render();
      Display.sync(FRAMERATE);
    }
  }
 
  private void render()
  {
    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
    GL11.glLoadIdentity();
  }
 
  private void logic()
  {
    world.step();
  }
}


And another question : what is the bitmask on the body ?  Huh
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline kevglass

JGO Kernel


Medals: 153
Projects: 23
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #3 - Posted 2007-09-06 08:29:51 »

I'll try and work out whats going on tonight.

The bitmask is to allow collision groups. Each bit represents a group and they're compared at collision time, I've never used it but I believe it was originally intended to allow different collision methods within different groups.

Kev

Offline kevglass

JGO Kernel


Medals: 153
Projects: 23
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #4 - Posted 2007-09-06 08:49:50 »

Just gave it a quick try and there's no memory increase here - runs with the 16meg default stack. I'm running against the latest code from SVN which appears to have been updated on 20/08/07, so it may just be that last bug fix isn't in the most recent build.

I'll kick off a new build now.

Kev

Offline kevglass

JGO Kernel


Medals: 153
Projects: 23
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #5 - Posted 2007-09-06 09:06:34 »

BUILD SUCCESSFUL

http://www.cokeandcode.com/phys2d/

JAR HERE: http://www.cokeandcode.com/phys2d/source/builds/phys2d-060907.jar

Kev

Offline Bonbon-Chan

JGO Coder


Medals: 12



« Reply #6 - Posted 2007-09-06 10:20:58 »

It run for 20mn without any problem now, thanks  Grin

I should look in more detail how bitmask works since i have a type of body that collide with nothing.
Offline kevglass

JGO Kernel


Medals: 153
Projects: 23
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #7 - Posted 2007-09-06 10:45:30 »

You can also use exlusison on bodies for that.

Glad it worked out Smiley

Kev

Offline Bonbon-Chan

JGO Coder


Medals: 12



« Reply #8 - Posted 2007-09-07 13:39:11 »

I continue to work with Phys2D  Wink

For exclusion, i use bitmask :
1  
2  
3  
4  
    public  static final long  MASK_NONE       = 0;
    public  static final long  MASK_ROAD_CAR   = 1;
    public  static final long  MASK_CAR_CAR    = 2;
    public  static final long  MASK_OPTION_CAR = 4;


For "road" body, i use MASK_ROAD_CAR.
For "car" body, i use MASK_ROAD_CAR | MASK_CAR_CAR | MASK_OPTION_CAR
...
It work fine. But i came accros another problem  Tongue

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
for(int i=0;i<NB_V;i++)
      {
        cars[i].step();
      }
     
world.step();
     
for(int i=0;i<NB_V;i++)
      {
        int val = map.crossStart(cars[i]);
       
        if (val != 0) { System.out.println("Start : "+val); }
      }


In Map.crossStart, I test if a car cross the start line.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
public int crossStart(Car car)
    {
      float cx1 = car.getPosition().getX();
      float cy1 = car.getPosition().getY();
     
      float cx2 = car.getLastPosition().getX();
      float cy2 = car.getLastPosition().getY();
     
      Line l = (Line)start.getShape();
     
      float sx1 = l.getX1();
      float sy1 = l.getY1();
     
      float sx2 = l.getX2();
      float sy2 = l.getY2();
     
      float nx = (sx2-sx1);
      float ny = (sy2-sy1);
     
      int signe1 = (int)Math.signum((cx1-sx1)*(ny)-(cy1-sy1)*(nx));
      int signe2 = (int)Math.signum((cx2-sx1)*(ny)-(cy2-sy1)*(nx));
       
      if (signe1 == signe2) { return 0; }
     
      float ln = (float)(Math.sqrt(nx*nx+ny*ny));
     
      nx = nx/ln;
      ny = ny/ln;

      float dist = (cx1-sx1)*nx+(cy1-sy1)*ny;
     
      if ((dist<0)||(dist>ln)) { return 0; }
     
      return signe1;
    }


If i use the Body.getLastPosition to do the test, it didn't work.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
class Car
{
[...]
public ROVector2f getPosition()
    {
      return body.getPosition();
    }
       
public ROVector2f getLastPosition()
    {
      return body.getLastPosition();      
    }


If i store the current possition before World.step(), it work.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
class Car
{
[...]
public ROVector2f getPosition()
    {
      return body.getPosition();
    }
   
public void step()
    {
      lastPosition.set(body.getPosition().getX(),body.getPosition().getY());
    }
   
public ROVector2f getLastPosition()
    {        
       return lastPosition;
    }
}


Body.getLastPosition didn't mean to return the position of the body before the world.step() ?
Offline kevglass

JGO Kernel


Medals: 153
Projects: 23
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #9 - Posted 2007-09-07 15:38:23 »

At the moment lastPosition is set every time adjustPosition() is called on a body. So if the body was moved a few times as part of your step then the lastPosition won't be the one before the step(). The lastPosition is intended for use when recieving notifications of collisions. The approach you've used as a work around is more suitable for what you're trying to do.

Kev

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Bonbon-Chan

JGO Coder


Medals: 12



« Reply #10 - Posted 2007-09-07 18:41:06 »

Ok thanks  Smiley

If there is a documentation that i didn't see, just let me know (i only use Javadoc)
Offline kevglass

JGO Kernel


Medals: 153
Projects: 23
Exp: 18 years


Coder, Trainee Pixel Artist, Game Reviewer


« Reply #11 - Posted 2007-09-07 19:32:59 »

I'm afraid the only documentation so far is the Javadoc. I'm not actively using the project so creating tutorial information isn't high on the agenda.

Kev

Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

atombrot (26 views)
2014-08-19 09:29:53

Tekkerue (24 views)
2014-08-16 06:45:27

Tekkerue (23 views)
2014-08-16 06:22:17

Tekkerue (14 views)
2014-08-16 06:20:21

Tekkerue (22 views)
2014-08-16 06:12:11

Rayexar (60 views)
2014-08-11 02:49:23

BurntPizza (39 views)
2014-08-09 21:09:32

BurntPizza (30 views)
2014-08-08 02:01:56

Norakomi (37 views)
2014-08-06 19:49:38

BurntPizza (67 views)
2014-08-03 02:57:17
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!