Changeset 82

Show
Ignore:
Timestamp:
08/03/08 20:51:06 (4 months ago)
Author:
JoeCoder
Message:

--

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/yage/core/array.d

    r81 r82  
    1818 
    1919import std.stdio; 
     20import std.random; 
     21import yage.core.types; 
    2022 
    2123/** 
  • trunk/src/yage/core/timer.d

    r81 r82  
    2727 * -------------------------------- 
    2828 */ 
    29 class Timer 
     29class Timer /* implements ITemporal */ // This would require core to depend on system. 
    3030{ 
    31     protected bool      paused  = false; 
     31    protected bool      _paused = false; 
     32    protected double    pause_after = double.infinity; 
    3233    protected double    min     = 0; 
    33     protected double    max     = real.infinity; 
     34    protected double    max     = double.infinity; 
    3435    //protected double  speed   = 1.0; 
    3536    protected ulong     us      = 0;        // microsecond counter 
     
    3738 
    3839    /// Initialize and start the Timer. 
    39     this(
     40    this(bool start=true
    4041    {   hpc = new PerformanceCounter(); 
    41         hpc.start(); 
     42        _paused = !start; 
     43        if (start) 
     44            hpc.start(); 
    4245    } 
    4346 
    44     /** Copy Constructor 
     47    /**  
     48     * Copy Constructor 
    4549     * Params: rhs = This Timer will be a copy of rhs.*/ 
    4650    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); 
    49167    } 
    50168 
    51     /// Return the Timer's time in seconds 
     169    /// @deprecated alias of tell(). 
    52170    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    } 
    68173 
    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();         
    70182    }    
    71183 
    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 
    94185    void resume() 
    95186    {   setPaused(false); 
    96187    } 
    97188 
    98     /// Reset the Timer to zero. 
     189    /// @deprecated 
    99190    void reset() 
    100191    {   synchronized(this) 
     
    105196        } 
    106197    } 
    107  
    108     /** Set the Timer 
    109      *  Params: time = Measured in seconds. */ 
    110     void set(double time) 
    111     in { assert(time>=0); } 
    112     body 
    113     {   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     } 
    132198} 
  • trunk/src/yage/core/vector.d

    r81 r82  
    2121 * -------------------------------- 
    2222 * Vec!(4, real) a; // a is a four-component real vector. 
    23  * --------------------------------*/ 
     23 * -------------------------------- 
     24 */ 
    2425struct Vec(int S, T) 
    2526{ 
  • trunk/src/yage/gui/surface.d

    r81 r82  
    2121import yage.resource.image; 
    2222import yage.gui.style; 
    23 import yage.system.rendertarget
     23import yage.system.interfaces
    2424 
    2525 
  • trunk/src/yage/resource/all.d

    r81 r82  
    1414 
    1515public 
    16 {   import yage.resource.exception; 
    17     import yage.resource.font; 
     16{   import yage.resource.font; 
    1817    import yage.resource.image; 
    1918    import yage.resource.layer; 
  • trunk/src/yage/resource/font.d

    r81 r82  
    1515import yage.core.types; 
    1616import yage.core.parse; 
    17 import yage.resource.exception
     17import yage.system.exceptions
    1818import yage.resource.resource; 
    1919import yage.resource.image; 
  • trunk/src/yage/resource/material.d

    r81 r82  
    1414import std.stdio; 
    1515import yage.core.all; 
    16 import yage.resource.exception
     16import yage.system.exceptions
    1717import yage.resource.texture; 
    1818import yage.resource.resource; 
  • trunk/src/yage/resource/model.d

    r81 r82  
    77module yage.resource.model; 
    88 
     9import std.c.math : fmod; 
    910import std.string; 
    1011import std.file; 
     
    1920import yage.core.quatrn; 
    2021import yage.core.vector; 
    21  
    22 import yage.resource.exception; 
     22import yage.system.exceptions; 
    2323import yage.resource.material; 
    2424import yage.resource.mesh; 
    2525import yage.resource.resource; 
    26 import yage.scene.visible; 
    2726import yage.system.constant; 
    2827import yage.system.device; 
    2928import yage.system.log; 
    30  
    3129import yage.resource.ms3dloader; 
    3230import yage.resource.objloader; 
     31import yage.scene.visible; 
    3332 
    3433 
     
    109108 
    110109    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; 
    113113    protected Joint[] joints; // used for skeletal animation 
    114114    protected int[] joint_indices; 
     
    161161     
    162162     
    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) 
    165169    { 
    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; 
    169176         
    170177        // TODO: check time constraints      
     
    295302    } 
    296303     
    297     /// 
     304    /** 
     305     * Get the requested attribute. 
     306     * @throws Exception if the attribute is not defined. */ 
    298307    Attribute getAttribute(char[] name) 
    299308    {   return attributes[name]; 
    300309    } 
    301310 
    302     /// Get the dimensions of a box, centered at the origin, 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
    305314        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)
    311320    } 
    312321 
     
    316325    Joint[] getJoints() 
    317326    {   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;       
    318340    } 
    319341     
  • trunk/src/yage/resource/ms3dloader.d

    r81 r82  
    1515import yage.core.color; 
    1616import yage.resource.all; 
    17 import yage.resource.exception
     17import yage.system.exceptions
    1818import yage.system.log; 
    1919 
     
    366366            {   joints[j].positions[k].time = ms3d.joints[j].keyFramesTrans[k].time; 
    367367                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; 
    370370            } 
    371371            for (int k=0; k<joints[j].rotations.length; k++) 
    372372            {   joints[j].rotations[k].time = ms3d.joints[j].keyFramesRot[k].time; 
    373373                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; 
    376376            } 
    377377        } 
     
    396396         
    397397        if (joints.length) 
    398         {    
     398        {   animated = true; 
     399             
    399400            // Sets up each joint's transformation matrices 
    400401            foreach(joint; joints) 
     
    417418                    vertices[i] = vertices[i].inverseTransform(matrix);          
    418419            }   } 
     420             
     421             
    419422        }    
    420423                 
     
    423426        setAttribute("gl_Normal", normals); 
    424427        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. 
    426429    } 
    427430} 
  • trunk/src/yage/scene/graph.d

    r73 r82  
    103103    void setSize(Vec3f size) 
    104104    {   this.size = size; 
    105         radius = model.getDimensions().scale(size).length(); 
     105        radius = model.getRadius() * size.max(); 
    106106    }    
    107107    Vec3f getSize() /// Ditto 
     
    228228        model.getMeshes()[0].setTriangles(triangles); 
    229229 
    230         radius = model.getDimensions().scale(size).max(); 
     230        radius = model.getRadius()*size.max(); 
    231231 
    232232        // Cache model in video memory 
  • trunk/src/yage/scene/model.d

    r81 r82  
    1111import yage.system.device; 
    1212import yage.system.log; 
     13import yage.system.interfaces; 
    1314import yage.resource.resource; 
    1415import yage.resource.model; 
     
    2526     
    2627    protected Timer animation_timer; 
     28    protected bool animation_looping = false; 
    2729 
    2830    /// Construct this Node as a child of parent. 
     
    4345 
    4446     
    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() 
    4669    {   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; 
    5572    } 
    5673 
    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      
    8474     
    8575    /// Get / set the 3D model that is being used by this Node. 
     
    8979    void setModel(Model model) /// ditto 
    9080    {   this.model = model; 
    91         radius = model.getDimensions().scale(size).length(); 
     81        radius = model.getRadius()*size.max(); 
    9282    } 
    9383 
     
    10191    /// Overridden to cache the radius if changed by the scale. 
    10292    void setSize(Vec3f s) 
    103     {   super.size = Vec3f(s.x, s.y, s.z)
     93    {   super.size = s
    10494        if (model) 
    105             radius = model.getDimensions().scale(size).max(); 
     95            radius = model.getRadius()*size.max(); 
    10696    }    
    10797    Vec3f getSize() /// Ditto 
  • trunk/src/yage/scene/sound.d

    r81 r82  
    1212import derelict.openal.al; 
    1313import yage.core.math; 
     14import yage.system.interfaces; 
    1415import yage.resource.resource; 
    1516import yage.resource.sound; 
     
    2021 
    2122/// A node that emits a sound. 
    22 class SoundNode : MovableNode 
     23class SoundNode : MovableNode, ITemporal 
    2324{   protected: 
    2425 
     
    3031    float       volume = 1.0; 
    3132    bool        looping = false; 
    32     bool        paused  = true;   // true if paused or stopped 
     33    bool        _paused  = true;  // true if paused or stopped 
    3334 
    3435    int         size;           // number of buffers that we use at one time 
     
    6465        setVolume(original.volume); 
    6566        setLooping(original.looping); 
    66         setPaused(original.paused); 
     67        if (original._paused) 
     68            pause(); 
     69        else 
     70            play(); 
    6771    } 
    6872 
     
    9094        size = len < sec ? len : sec; 
    9195 
    92         setPaused(tpaused); 
     96        if (tpaused) 
     97            pause(); 
     98        else 
     99            play(); 
    93100    } 
    94101 
     
    155162 
    156163    /// 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(
    163170    {   // 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; 
    166185            if (paused) 
    167186                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        } 
    184188    } 
    185189 
     
    204208 
    205209        buffer_start = buffer_end = secs; 
    206         setPaused(paused); 
     210        if (_paused) 
     211            pause(); 
     212        else 
     213            play(); 
    207214    } 
    208215 
     
    217224    /// Stop the SoundNode from playing and rewind it to the beginning. 
    218225    void stop() 
    219     {   paused     = true
     226    {   pause()
    220227        enqueue     = false; 
    221228        if (sound !is null) 
  • trunk/src/yage/scene/terrain.d

    r81 r82  
    153153    {   this.scale = scale; 
    154154        if (width != 0) // if heightmap loaded 
    155             radius = model.getDimensions().scale(scale).length(); 
     155            radius = model.getRadius()*scale.max(); 
    156156    } 
    157157     
     
    159159    {   return super.size;       
    160160    } 
    161      
    162      
    163161 
    164162    /* 
     
    199197        model.setAttribute("gl_Normal", normals); 
    200198         
    201         radius = model.getDimensions().scale(scale).length(); 
     199        radius = model.getRadius()*size.max(); 
    202200    } 
    203201} 
  • trunk/src/yage/system/all.d

    r81 r82  
    1212{   import yage.system.constant; 
    1313    import yage.system.device; 
     14    import yage.system.exceptions; 
    1415    import yage.system.input; 
     16    import yage.system.interfaces; 
    1517    import yage.system.log; 
    1618    import yage.system.render; 
    17     import yage.system.rendertarget; 
    1819} 
  • trunk/src/yage/system/render.d

    r81 r82  
    1919import yage.resource.mesh; 
    2020import yage.scene.all; 
     21import yage.scene.model; 
    2122import yage.scene.camera: CameraNode; 
    2223 
     
    169170        Matrix abs_transform = node.getAbsoluteTransform(true); 
    170171        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        } 
    171186 
    172187        // Rotate if rotation is nonzero.