OSDN Git Service

Set optimal mime types and executable settings.
[mikumikustudio/MikuMikuStudio.git] / src / com / jme / util / lwjgl / LWJGLTimer.java
1 /*
2  * Copyright (c) 2003-2009 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 
17  *   may be used to endorse or promote products derived from this software 
18  *   without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 package com.jme.util.lwjgl;
34
35 import java.util.logging.Logger;
36
37 import com.jme.math.FastMath;
38 import com.jme.util.Timer;
39 import org.lwjgl.Sys;
40
41 /**
42  * <code>Timer</code> handles the system's time related functionality. This
43  * allows the calculation of the framerate. To keep the framerate calculation
44  * accurate, a call to update each frame is required. <code>Timer</code> is a
45  * singleton object and must be created via the <code>getTimer</code> method.
46  *
47  * @author Mark Powell
48  * @version $Id: LWJGLTimer.java,v 1.21 2007/09/22 16:46:35 irrisor Exp $
49  */
50 public class LWJGLTimer extends Timer {
51     private static final Logger logger = Logger.getLogger(LWJGLTimer.class
52             .getName());
53
54     private long lastFrameDiff;
55
56     //frame rate parameters.
57     private long oldTime;
58
59     private float lastTPF, lastFPS;
60
61     public static int TIMER_SMOOTHNESS = 32;
62
63     private long[] tpf;
64
65     private int smoothIndex;
66
67     private final static long timerRez = Sys.getTimerResolution();
68     private final static float invTimerRez = ( 1f / timerRez );
69     private static float invTimerRezSmooth;
70
71     private long startTime;
72
73     private boolean allSmooth = false;
74
75     /**
76      * Constructor builds a <code>Timer</code> object. All values will be
77      * initialized to it's default values.
78      */
79     public LWJGLTimer() {
80         reset();
81
82         //print timer resolution info
83         logger.info("Timer resolution: " + timerRez + " ticks per second");
84     }
85
86     public void reset() {
87         lastFrameDiff = 0;
88         lastFPS = 0;
89         lastTPF = 0;
90
91         // init to -1 to indicate this is a new timer.
92         oldTime = -1;
93         //reset time
94         startTime = Sys.getTime();
95
96         tpf = new long[TIMER_SMOOTHNESS];
97         smoothIndex = TIMER_SMOOTHNESS - 1;
98         invTimerRezSmooth = ( 1f / (timerRez * TIMER_SMOOTHNESS));
99         
100         // set tpf... -1 values will not be used for calculating the average in update()
101         for ( int i = tpf.length; --i >= 0; ) {
102             tpf[i] = -1;
103         }
104     }
105
106     /**
107      * @see com.jme.util.Timer#getTime()
108      */
109     public long getTime() {
110         return Sys.getTime() - startTime;
111     }
112
113     /**
114      * @see com.jme.util.Timer#getResolution()
115      */
116     public long getResolution() {
117         return timerRez;
118     }
119
120     /**
121      * <code>getFrameRate</code> returns the current frame rate since the last
122      * call to <code>update</code>.
123      *
124      * @return the current frame rate.
125      */
126     public float getFrameRate() {
127         return lastFPS;
128     }
129
130     public float getTimePerFrame() {
131         return lastTPF;
132     }
133
134     /**
135      * <code>update</code> recalulates the frame rate based on the previous
136      * call to update. It is assumed that update is called each frame.
137      */
138     public void update() {
139         long newTime = Sys.getTime();
140         long oldTime = this.oldTime;
141         this.oldTime = newTime;
142         if ( oldTime == -1 ) {
143             // For the first frame use 60 fps. This value will not be counted in further averages.
144             // This is done so initialization code between creating the timer and the first
145             // frame is not counted as a single frame on it's own.
146             lastTPF = 1 / 60f;
147             lastFPS = 1f / lastTPF;
148             return;
149         }
150
151         long frameDiff = newTime - oldTime;
152         long lastFrameDiff = this.lastFrameDiff;
153         if ( lastFrameDiff > 0 && frameDiff > lastFrameDiff *100 ) {
154             frameDiff = lastFrameDiff *100;
155         }
156         this.lastFrameDiff = frameDiff;
157         tpf[smoothIndex] = frameDiff;
158         smoothIndex--;
159         if ( smoothIndex < 0 ) {
160             smoothIndex = tpf.length - 1;
161         }
162
163         lastTPF = 0.0f;
164         if (!allSmooth) {
165             int smoothCount = 0;
166             for ( int i = tpf.length; --i >= 0; ) {
167                 if ( tpf[i] != -1 ) {
168                     lastTPF += tpf[i];
169                     smoothCount++;
170                 }
171             }
172             if (smoothCount == tpf.length)
173                 allSmooth  = true;
174             lastTPF *= ( invTimerRez / smoothCount );
175         } else {
176             for ( int i = tpf.length; --i >= 0; ) {
177                 if ( tpf[i] != -1 ) {
178                     lastTPF += tpf[i];
179                 }
180             }
181             lastTPF *= invTimerRezSmooth;
182         }
183         if ( lastTPF < FastMath.FLT_EPSILON ) {
184             lastTPF = FastMath.FLT_EPSILON;
185         }
186
187         lastFPS = 1f / lastTPF;
188     }
189
190     /**
191      * <code>toString</code> returns the string representation of this timer
192      * in the format: <br>
193      * <br>
194      * jme.utility.Timer@1db699b <br>
195      * Time: {LONG} <br>
196      * FPS: {LONG} <br>
197      *
198      * @return the string representation of this object.
199      */
200     public String toString() {
201         String string = super.toString();
202         string += "\nTime: " + oldTime;
203         string += "\nFPS: " + getFrameRate();
204         return string;
205     }
206 }