Changeset 82
- Timestamp:
- 08/03/08 20:51:06 (4 months ago)
- Files:
-
- trunk/src/yage/core/array.d (modified) (1 diff)
- trunk/src/yage/core/timer.d (modified) (3 diffs)
- trunk/src/yage/core/vector.d (modified) (1 diff)
- trunk/src/yage/gui/surface.d (modified) (1 diff)
- trunk/src/yage/resource/all.d (modified) (1 diff)
- trunk/src/yage/resource/exception.d (deleted)
- trunk/src/yage/resource/font.d (modified) (1 diff)
- trunk/src/yage/resource/material.d (modified) (1 diff)
- trunk/src/yage/resource/model.d (modified) (6 diffs)
- trunk/src/yage/resource/ms3dloader.d (modified) (5 diffs)
- trunk/src/yage/scene/graph.d (modified) (2 diffs)
- trunk/src/yage/scene/model.d (modified) (5 diffs)
- trunk/src/yage/scene/sound.d (modified) (8 diffs)
- trunk/src/yage/scene/terrain.d (modified) (3 diffs)
- trunk/src/yage/system/all.d (modified) (1 diff)
- trunk/src/yage/system/playable.d (deleted)
- trunk/src/yage/system/render.d (modified) (2 diffs)
- trunk/src/yage/system/rendertarget.d (deleted)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/yage/core/array.d
r81 r82 18 18 19 19 import std.stdio; 20 import std.random; 21 import yage.core.types; 20 22 21 23 /** trunk/src/yage/core/timer.d
r81 r82 27 27 * -------------------------------- 28 28 */ 29 class Timer 29 class Timer /* implements ITemporal */ // This would require core to depend on system. 30 30 { 31 protected bool paused = false; 31 protected bool _paused = false; 32 protected double pause_after = double.infinity; 32 33 protected double min = 0; 33 protected double max = real.infinity;34 protected double max = double.infinity; 34 35 //protected double speed = 1.0; 35 36 protected ulong us = 0; // microsecond counter … … 37 38 38 39 /// Initialize and start the Timer. 39 this( )40 this(bool start=true) 40 41 { hpc = new PerformanceCounter(); 41 hpc.start(); 42 _paused = !start; 43 if (start) 44 hpc.start(); 42 45 } 43 46 44 /** Copy Constructor 47 /** 48 * Copy Constructor 45 49 * Params: rhs = This Timer will be a copy of rhs.*/ 46 50 this(Timer rhs) 47 { paused = rhs.paused; 48 set(rhs.get()); 51 { seek(rhs.get()); 52 min = rhs.min; 53 max = rhs.max; 54 if (rhs.paused()) 55 pause(); 56 else 57 play(); 58 } 59 60 /** 61 * Stop the timer. When play() is called again, it will start from the time when it was paused. */ 62 void pause() 63 { synchronized(this) 64 { _paused = true; 65 hpc.stop(); 66 us += hpc.microseconds(); 67 } 68 } 69 70 /// Is the Timer paused? 71 bool paused() 72 { return _paused; 73 } 74 75 /** 76 * Start the timer. */ 77 void play() 78 { synchronized(this) 79 { _paused = false; 80 hpc.start(); 81 } 82 } 83 84 /** 85 * Stop the timer and reset its position.*/ 86 void stop() 87 { synchronized(this) 88 { _paused = true; 89 hpc.stop(); 90 us = cast(ulong)(min*1000000); 91 } 92 } 93 94 /** 95 * Pause the timer when it reaches this amount. 96 * Must be between (inclusive) the arguments of setRange(min, max) or else it will be ignored. 97 * Use pauseAfter(double.infinity) to clear pauseAfter. */ 98 void pauseAfter(double seconds) 99 { pause_after = seconds; 100 } 101 102 /** 103 * Set the Timer. */ 104 void seek(double seconds) 105 in { assert(seconds>=0); } 106 body 107 { us = cast(ulong)(seconds*1000000); 108 } 109 110 /** 111 * Get the Timer's time in seconds. */ 112 double tell() 113 { 114 synchronized(this) 115 { if (!_paused) 116 { hpc.stop(); 117 us += hpc.microseconds(); // Update our microsecond counter 118 hpc.start(); 119 } 120 121 double relative = us*0.000001; 122 123 // Only use pause_after if it's between min and max. 124 if (min <= pause_after && pause_after <= max) 125 if (relative > pause_after) 126 return pause_after; 127 128 // employ floating point modulus division to keep between min and max. 129 real range = max-min; 130 if (relative > max) 131 relative = min + fmod(relative-min, range); 132 if (relative < min) 133 relative = max + fmod(relative-max, range); 134 135 return relative; 136 } 137 } 138 139 /** 140 * Set the timers roll-under and roll-over values. 141 * Provide no arguments to reset them to the defaults of 0 and infinity. 142 * Params: 143 * min = The timer will never be less than this value. 144 * max = The timer will never be greater than this value and will rollover back to min after crossing it.*/ 145 void setRange(double min=0, double max=double.infinity) 146 { this.min = min; 147 this.max = max; 148 } 149 150 /// 151 char[] toString() 152 { return .toString(get()); 153 } 154 155 156 157 158 159 160 161 162 163 164 /// @deprecated 165 void set(real time) 166 { seek(time); 49 167 } 50 168 51 /// Return the Timer's time in seconds169 /// @deprecated alias of tell(). 52 170 real get() 53 { // Update our microsecond counter 54 synchronized(this) 55 { if (!paused) 56 { hpc.stop(); 57 us += hpc.microseconds(); 58 hpc.start(); 59 } 60 } 61 double relative = us*0.000001; 62 63 real range = max-min; 64 if (relative > max) 65 relative = min + fmod(relative-min, range); 66 if (relative < min) 67 relative = max + fmod(relative-max, range); 171 { return tell(); 172 } 68 173 69 return relative; 174 /// @deprecated Is the Timer paused? 175 bool getPaused() 176 { return paused(); 177 } 178 179 /// @deprecated Set whether the Timer is paused. 180 void setPaused(bool paused) 181 { pause(); 70 182 } 71 183 72 /// Is the Timer paused? 73 bool getPaused() 74 { return paused; 75 } 76 77 /// Set whether the Timer is paused. 78 void setPaused(bool paused) 79 { synchronized(this) 80 { this.paused = paused; 81 if (paused) 82 { hpc.stop(); 83 us += hpc.microseconds(); 84 }else 85 hpc.start(); 86 } } 87 88 /// Alias of setPaused(true) 89 void pause() 90 { setPaused(true); 91 } 92 93 /// Alias of setPaused(false) 184 /// @deprecated 94 185 void resume() 95 186 { setPaused(false); 96 187 } 97 188 98 /// Reset the Timer to zero.189 /// @deprecated 99 190 void reset() 100 191 { synchronized(this) … … 105 196 } 106 197 } 107 108 /** Set the Timer109 * Params: time = Measured in seconds. */110 void set(double time)111 in { assert(time>=0); }112 body113 { us = cast(ulong)(time*1000000);114 }115 116 117 /**118 * Set the timers rollunder and rollover values.119 * Provide no arguments to reset them to the defaults of 0 and infinity.120 * Params:121 * min = The timer will never be less than this value.122 * max = The timer will never be greater than this value and will rollover back to min after crossing it.*/123 void setBounds(double min=0, double max=double.infinity)124 { this.min = min;125 this.max = max;126 }127 128 129 char[] toString()130 { return .toString(get());131 }132 198 } trunk/src/yage/core/vector.d
r81 r82 21 21 * -------------------------------- 22 22 * Vec!(4, real) a; // a is a four-component real vector. 23 * --------------------------------*/ 23 * -------------------------------- 24 */ 24 25 struct Vec(int S, T) 25 26 { trunk/src/yage/gui/surface.d
r81 r82 21 21 import yage.resource.image; 22 22 import yage.gui.style; 23 import yage.system. rendertarget;23 import yage.system.interfaces; 24 24 25 25 trunk/src/yage/resource/all.d
r81 r82 14 14 15 15 public 16 { import yage.resource.exception; 17 import yage.resource.font; 16 { import yage.resource.font; 18 17 import yage.resource.image; 19 18 import yage.resource.layer; trunk/src/yage/resource/font.d
r81 r82 15 15 import yage.core.types; 16 16 import yage.core.parse; 17 import yage. resource.exception;17 import yage.system.exceptions; 18 18 import yage.resource.resource; 19 19 import yage.resource.image; trunk/src/yage/resource/material.d
r81 r82 14 14 import std.stdio; 15 15 import yage.core.all; 16 import yage. resource.exception;16 import yage.system.exceptions; 17 17 import yage.resource.texture; 18 18 import yage.resource.resource; trunk/src/yage/resource/model.d
r81 r82 7 7 module yage.resource.model; 8 8 9 import std.c.math : fmod; 9 10 import std.string; 10 11 import std.file; … … 19 20 import yage.core.quatrn; 20 21 import yage.core.vector; 21 22 import yage.resource.exception; 22 import yage.system.exceptions; 23 23 import yage.resource.material; 24 24 import yage.resource.mesh; 25 25 import yage.resource.resource; 26 import yage.scene.visible;27 26 import yage.system.constant; 28 27 import yage.system.device; 29 28 import yage.system.log; 30 31 29 import yage.resource.ms3dloader; 32 30 import yage.resource.objloader; 31 import yage.scene.visible; 33 32 34 33 … … 109 108 110 109 protected float fps=24; 111 protected float animation_time=0; 112 protected float max_time=0; 110 protected bool animated = false; 111 protected double animation_time=0; 112 protected double animation_max_time=0; 113 113 protected Joint[] joints; // used for skeletal animation 114 114 protected int[] joint_indices; … … 161 161 162 162 163 /// 164 void animate(float time) 163 /** 164 * Advance this Model's animation to time. 165 * Params: 166 * time = 167 */ 168 void animateTo(double time) 165 169 { 166 real temp = max_time; 167 while (time > max_time) 168 time-= max_time; // since modf doesn't seem to work right. 170 // If nothing to do. 171 if (animation_time == time) 172 return; 173 174 time = fmod(time, animation_max_time); 175 animation_time = time; 169 176 170 177 // TODO: check time constraints … … 295 302 } 296 303 297 /// 304 /** 305 * Get the requested attribute. 306 * @throws Exception if the attribute is not defined. */ 298 307 Attribute getAttribute(char[] name) 299 308 { return attributes[name]; 300 309 } 301 310 302 /// Get the dimensions of a box, centered at theorigin, that can contain this Model.303 Vec3f getDimensions()304 { Vec3f result;311 /// Get radius of a sphere, centered at the model's origin, that can contain this Model. 312 float getRadius() 313 { float result=0; 305 314 foreach (Vec3f v; getAttribute("gl_Vertex").vec3f) 306 { if (abs(v.x) > result.x) result.x=v.x;307 if ( abs(v.y) > result.y) result.y=v.y;308 if (abs(v.z) > result.z) result.z=v.z;309 } 310 return result;315 { float length2 = v.length2(); 316 if (length2 > result) 317 result = length2; 318 } 319 return sqrt(result); 311 320 } 312 321 … … 316 325 Joint[] getJoints() 317 326 { return joints; 327 } 328 329 /** 330 * Get whether this model is animated. */ 331 bool getAnimated() 332 { return animated; 333 } 334 335 336 /** 337 * Get the time in seconds of the end of this Model's skeletal animation.*/ 338 double getAnimationMax() 339 { return animation_max_time; 318 340 } 319 341 trunk/src/yage/resource/ms3dloader.d
r81 r82 15 15 import yage.core.color; 16 16 import yage.resource.all; 17 import yage. resource.exception;17 import yage.system.exceptions; 18 18 import yage.system.log; 19 19 … … 366 366 { joints[j].positions[k].time = ms3d.joints[j].keyFramesTrans[k].time; 367 367 joints[j].positions[k].value.v[0..3] = ms3d.joints[j].keyFramesTrans[k].position[0..3]; 368 if (joints[j].positions[k].time > max_time)369 max_time = joints[j].positions[k].time;368 if (joints[j].positions[k].time > animation_max_time) 369 animation_max_time = joints[j].positions[k].time; 370 370 } 371 371 for (int k=0; k<joints[j].rotations.length; k++) 372 372 { joints[j].rotations[k].time = ms3d.joints[j].keyFramesRot[k].time; 373 373 joints[j].rotations[k].value.v[0..3] = ms3d.joints[j].keyFramesRot[k].rotation[0..3]; 374 if (joints[j].rotations[k].time > max_time)375 max_time = joints[j].rotations[k].time;374 if (joints[j].rotations[k].time > animation_max_time) 375 animation_max_time = joints[j].rotations[k].time; 376 376 } 377 377 } … … 396 396 397 397 if (joints.length) 398 { 398 { animated = true; 399 399 400 // Sets up each joint's transformation matrices 400 401 foreach(joint; joints) … … 417 418 vertices[i] = vertices[i].inverseTransform(matrix); 418 419 } } 420 421 419 422 } 420 423 … … 423 426 setAttribute("gl_Normal", normals); 424 427 setAttribute("gl_VertexOriginal", vertices.dup); // a copy of these 425 setAttribute("gl_NormalOriginal", vertices.dup); // is required for skeletal animation.428 setAttribute("gl_NormalOriginal", normals.dup); // is required for skeletal animation. 426 429 } 427 430 } trunk/src/yage/scene/graph.d
r73 r82 103 103 void setSize(Vec3f size) 104 104 { this.size = size; 105 radius = model.get Dimensions().scale(size).length();105 radius = model.getRadius() * size.max(); 106 106 } 107 107 Vec3f getSize() /// Ditto … … 228 228 model.getMeshes()[0].setTriangles(triangles); 229 229 230 radius = model.get Dimensions().scale(size).max();230 radius = model.getRadius()*size.max(); 231 231 232 232 // Cache model in video memory trunk/src/yage/scene/model.d
r81 r82 11 11 import yage.system.device; 12 12 import yage.system.log; 13 import yage.system.interfaces; 13 14 import yage.resource.resource; 14 15 import yage.resource.model; … … 25 26 26 27 protected Timer animation_timer; 28 protected bool animation_looping = false; 27 29 28 30 /// Construct this Node as a child of parent. … … 43 45 44 46 45 void setAnimation(float from, float to, bool looping=true) 47 /** 48 * Get the timer used for the skeletal animation of this model. 49 * If the model has no joints and keyframes for skeletal animation, modifying this timer will do nothing. 50 * TODO: Implement a similar interface for SoundNode? 51 * 52 * See: yage.core.timer 53 * 54 * Example: 55 * -------------------------------- 56 * // Continuously play the model's skeletal animation from 5 to 12 seconds. 57 * Timer t1 = myModel.getAnimationTimer(); 58 * t1.setRange(5, 12); 59 * t1.play(); 60 * 61 * // Play the animation from 0 to 60 seconds and then stop. 62 * Timer t2 = myModel.getAnimationTimer(); 63 * t2.setRange(0, 60); 64 * t2.pauseAfter(60); 65 * t2.play(); 66 * -------------------------------- 67 */ 68 Timer getAnimationTimer() 46 69 { if (!animation_timer) 47 animation_timer = new Timer(); 48 49 } 50 51 /// Alias of setPaused(false); 52 void play() 53 { if (!animation_timer) 54 animation_timer = new Timer(); 70 animation_timer = new Timer(false); 71 return animation_timer; 55 72 } 56 73 57 /// Alias of setPaused(true);58 void pause()59 { if (!animation_timer)60 animation_timer = new Timer();61 }62 63 /** Seek to the position in the track. Seek has a precision of .05 seconds.64 * seek() throws an exception if the value is outside the range of the Sound. */65 void seek(double seconds)66 { if (!animation_timer)67 animation_timer = new Timer();68 }69 70 /// Tell the position of the playback of the current sound file, in seconds.71 double tell()72 { if (!animation_timer)73 animation_timer = new Timer();74 return 1.0;75 }76 77 /// Stop the SoundNode from playing and rewind it to the beginning.78 void stop()79 { if (!animation_timer)80 animation_timer = new Timer();81 }82 83 84 74 85 75 /// Get / set the 3D model that is being used by this Node. … … 89 79 void setModel(Model model) /// ditto 90 80 { this.model = model; 91 radius = model.get Dimensions().scale(size).length();81 radius = model.getRadius()*size.max(); 92 82 } 93 83 … … 101 91 /// Overridden to cache the radius if changed by the scale. 102 92 void setSize(Vec3f s) 103 { super.size = Vec3f(s.x, s.y, s.z);93 { super.size = s; 104 94 if (model) 105 radius = model.get Dimensions().scale(size).max();95 radius = model.getRadius()*size.max(); 106 96 } 107 97 Vec3f getSize() /// Ditto trunk/src/yage/scene/sound.d
r81 r82 12 12 import derelict.openal.al; 13 13 import yage.core.math; 14 import yage.system.interfaces; 14 15 import yage.resource.resource; 15 16 import yage.resource.sound; … … 20 21 21 22 /// A node that emits a sound. 22 class SoundNode : MovableNode 23 class SoundNode : MovableNode, ITemporal 23 24 { protected: 24 25 … … 30 31 float volume = 1.0; 31 32 bool looping = false; 32 bool paused = true; // true if paused or stopped33 bool _paused = true; // true if paused or stopped 33 34 34 35 int size; // number of buffers that we use at one time … … 64 65 setVolume(original.volume); 65 66 setLooping(original.looping); 66 setPaused(original.paused); 67 if (original._paused) 68 pause(); 69 else 70 play(); 67 71 } 68 72 … … 90 94 size = len < sec ? len : sec; 91 95 92 setPaused(tpaused); 96 if (tpaused) 97 pause(); 98 else 99 play(); 93 100 } 94 101 … … 155 162 156 163 /// Is the sound currently paused (or stopped?) 157 bool getPaused()158 { return paused;159 } 160 161 /// Set whether the playback of the SoundNode is paused.162 void setPaused(bool paused=true)164 bool paused() 165 { return _paused; 166 } 167 168 /// Alias of setPaused(false); 169 void play() 163 170 { // Only do something if changing states 164 if (this.paused != paused) 165 { this.paused = paused; 171 if (_paused) 172 { _paused = false; 173 if (sound is null) 174 throw new Exception("You cannot play or unpause a SoundNode without first calling setSound()."); 175 alSourcePlay(al_source); 176 enqueue = true; 177 } 178 } 179 180 /// Alias of setPaused(true); 181 void pause() 182 { // Only do something if changing states 183 if (!_paused) 184 { _paused = true; 166 185 if (paused) 167 186 alSourcePause(al_source); 168 else 169 { if (sound is null) 170 throw new Exception("You cannot play or unpause a SoundNode without first calling setSound()."); 171 alSourcePlay(al_source); 172 enqueue = true; 173 } } 174 } 175 176 /// Alias of setPaused(false); 177 void play() 178 { setPaused(false); 179 } 180 181 /// Alias of setPaused(true); 182 void pause() 183 { setPaused(true); 187 } 184 188 } 185 189 … … 204 208 205 209 buffer_start = buffer_end = secs; 206 setPaused(paused); 210 if (_paused) 211 pause(); 212 else 213 play(); 207 214 } 208 215 … … 217 224 /// Stop the SoundNode from playing and rewind it to the beginning. 218 225 void stop() 219 { pause d = true;226 { pause(); 220 227 enqueue = false; 221 228 if (sound !is null) trunk/src/yage/scene/terrain.d
r81 r82 153 153 { this.scale = scale; 154 154 if (width != 0) // if heightmap loaded 155 radius = model.get Dimensions().scale(scale).length();155 radius = model.getRadius()*scale.max(); 156 156 } 157 157 … … 159 159 { return super.size; 160 160 } 161 162 163 161 164 162 /* … … 199 197 model.setAttribute("gl_Normal", normals); 200 198 201 radius = model.get Dimensions().scale(scale).length();199 radius = model.getRadius()*size.max(); 202 200 } 203 201 } trunk/src/yage/system/all.d
r81 r82 12 12 { import yage.system.constant; 13 13 import yage.system.device; 14 import yage.system.exceptions; 14 15 import yage.system.input; 16 import yage.system.interfaces; 15 17 import yage.system.log; 16 18 import yage.system.render; 17 import yage.system.rendertarget;18 19 } trunk/src/yage/system/render.d
r81 r82 19 19 import yage.resource.mesh; 20 20 import yage.scene.all; 21 import yage.scene.model; 21 22 import yage.scene.camera: CameraNode; 22 23 … … 169 170 Matrix abs_transform = node.getAbsoluteTransform(true); 170 171 vertex_count += v.length; 172 173 // Apply skeletal animation. 174 if (cast(ModelNode)node) 175 { 176 if (model.getAnimated()) 177 { auto mnode = cast(ModelNode)node; 178 model.animateTo(mnode.getAnimationTimer().tell()); 179 180 // Forces an update of the node's culling radius. 181 // This isn't perfect, since this is after CameraNode's culling, but a model's radius is 182 // usually temporaly coherent so this takes advantage of that for the next render. 183 mnode.setModel(model); 184 } 185 } 171 186 172 187 // Rotate if rotation is nonzero.
