Revision: 21599
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21599
Author:   ben2610
Date:     2009-07-15 19:11:08 +0200 (Wed, 15 Jul 2009)

Log Message:
-----------
iTaSC: negative frame handling: add special item for rest pose in cache. Avoids 
using a full buffer or that.

Modified Paths:
--------------
    branches/itasc/intern/itasc/Armature.cpp
    branches/itasc/intern/itasc/Cache.cpp
    branches/itasc/intern/itasc/Cache.hpp
    branches/itasc/source/blender/ikplugin/intern/itasc_plugin.cpp

Modified: branches/itasc/intern/itasc/Armature.cpp
===================================================================
--- branches/itasc/intern/itasc/Armature.cpp    2009-07-15 16:25:45 UTC (rev 
21598)
+++ branches/itasc/intern/itasc/Armature.cpp    2009-07-15 17:11:08 UTC (rev 
21599)
@@ -76,6 +76,7 @@
                pushConstraints(0);
        }
 }
+
 void Armature::pushQ(CacheTS timestamp)
 {
        if (m_qCCh >= 0) {

Modified: branches/itasc/intern/itasc/Cache.cpp
===================================================================
--- branches/itasc/intern/itasc/Cache.cpp       2009-07-15 16:25:45 UTC (rev 
21598)
+++ branches/itasc/intern/itasc/Cache.cpp       2009-07-15 17:11:08 UTC (rev 
21599)
@@ -78,7 +78,10 @@
        }
        m_firstBuffer = NULL;
        m_lastBuffer = NULL;
-       m_busy = 0;
+       if (initItem) {
+               free(initItem);
+               initItem = NULL;
+       }
 }
 
 CacheBuffer* CacheChannel::allocBuffer()
@@ -99,6 +102,10 @@
        CacheItem *item, *limit;
        if (!m_busy)
                return NULL;
+       if (timestamp == 0 && initItem) {
+               *rBuffer = NULL;
+               return initItem;
+       }
        for (buffer=m_firstBuffer; buffer; buffer = buffer->m_next) {
                if (buffer->m_firstFreePositionW == 0)
                        // buffer is empty, this must be the last and we didn't 
find the timestamp
@@ -132,14 +139,17 @@
        CacheItem *item, *limit, *prevItem;
        if (!m_busy)
                return NULL;
+       if (timestamp == 0)
+               return NULL;
        for (prevBuffer=NULL, buffer=m_firstBuffer; buffer; prevBuffer = 
buffer, buffer = buffer->m_next) {
                if (buffer->m_firstFreePositionW == 0)
                        // buffer is empty, this must be the last and we didn't 
find the timestamp
                        return NULL;
                if (timestamp <= buffer->m_firstTimestamp) {
                        if (prevBuffer == NULL) {
-                               // no item before
-                               return NULL;
+                               // no item before, except the initial item
+                               *rBuffer = NULL;
+                               return initItem;
                        }
                        // the item is necessarily the last one of previous 
buffer
                        *rBuffer = prevBuffer;
@@ -166,8 +176,9 @@
        }
        // pass all buffer, the last item is the last item of the last buffer
        if (prevBuffer == NULL) {
-               // no item before
-               return NULL;
+               // no item before, except the initial item
+               *rBuffer = NULL;
+               return initItem;
        }
        // the item is necessarily the last one of previous buffer
        *rBuffer = prevBuffer;
@@ -265,6 +276,7 @@
        channel->m_firstBuffer = NULL;
        channel->m_lastBuffer = NULL;
        channel->m_busy = 1;
+       channel->initItem = NULL;
        channel->m_maxItemSizeB = maxItemSize;
        strncpy(channel->m_name, name, sizeof(channel->m_name));
        channel->m_name[sizeof(channel->m_name)-1] = 0;
@@ -287,6 +299,7 @@
        if (id < 0 || id >= (int)entry->m_count || 
!entry->m_channelArray[id].m_busy)
                return -1;
        entry->m_channelArray[id].clear();
+       entry->m_channelArray[id].m_busy = 0;
        return 0;
 }
 
@@ -321,58 +334,63 @@
                        if (channel->m_busy) {
                                item = channel->findItemOrLater(timestamp, 
&buffer);
                                if (item ) {
-                                       // this item and all later items will 
be removed, clear any later buffer
-                                       while ((nextBuffer = buffer->m_next) != 
NULL) {
-                                               buffer->m_next = 
nextBuffer->m_next;
-                                               free(nextBuffer);
-                                       }
-                                       positionW = 
CACHE_ITEM_POSITIONW(buffer,item);
-                                       if (positionW == 0) {
-                                               // this item is the first one 
of the buffer, remove the buffer completely
-                                               // first find the buffer just 
before it
-                                               nextBuffer = 
channel->m_firstBuffer;
-                                               prevBuffer = NULL;
-                                               while (nextBuffer != buffer) {
-                                                       prevBuffer = nextBuffer;
-                                                       nextBuffer = 
nextBuffer->m_next;
-                                                       // we must quit this 
loop before reaching the end of the list
-                                                       assert(nextBuffer);
+                                       if (!buffer) {
+                                               // this is possible if we 
return the special timestamp=0 item, delete all buffers
+                                               channel->clear();
+                                       } else {
+                                               // this item and all later 
items will be removed, clear any later buffer
+                                               while ((nextBuffer = 
buffer->m_next) != NULL) {
+                                                       buffer->m_next = 
nextBuffer->m_next;
+                                                       free(nextBuffer);
                                                }
-                                               free(buffer);
-                                               buffer = prevBuffer;
-                                               if (buffer == NULL)
-                                                       // this was also the 
first buffer
-                                                       channel->m_firstBuffer 
= NULL;
-                                       } else {
-                                               // removing this item means 
finding the previous item to make it the last one
-                                               block = 
positionW>>channel->m_positionToBlockShiftW;
-                                               if (block == 0) {
-                                                       // start from first 
item, we know it is not our item because positionW > 0
-                                                       prevItem = 
&buffer->m_firstItem;
+                                               positionW = 
CACHE_ITEM_POSITIONW(buffer,item);
+                                               if (positionW == 0) {
+                                                       // this item is the 
first one of the buffer, remove the buffer completely
+                                                       // first find the 
buffer just before it
+                                                       nextBuffer = 
channel->m_firstBuffer;
+                                                       prevBuffer = NULL;
+                                                       while (nextBuffer != 
buffer) {
+                                                               prevBuffer = 
nextBuffer;
+                                                               nextBuffer = 
nextBuffer->m_next;
+                                                               // we must quit 
this loop before reaching the end of the list
+                                                               
assert(nextBuffer);
+                                                       }
+                                                       free(buffer);
+                                                       buffer = prevBuffer;
+                                                       if (buffer == NULL)
+                                                               // this was 
also the first buffer
+                                                               
channel->m_firstBuffer = NULL;
                                                } else {
-                                                       // no need to check the 
current block, it will point to our item or a later one
-                                                       // but the previous 
block will be a good start for sure.
-                                                       block--;
-                                                       prevItem = 
CACHE_BLOCK_ITEM_ADDR(channel,buffer,block);
+                                                       // removing this item 
means finding the previous item to make it the last one
+                                                       block = 
positionW>>channel->m_positionToBlockShiftW;
+                                                       if (block == 0) {
+                                                               // start from 
first item, we know it is not our item because positionW > 0
+                                                               prevItem = 
&buffer->m_firstItem;
+                                                       } else {
+                                                               // no need to 
check the current block, it will point to our item or a later one
+                                                               // but the 
previous block will be a good start for sure.
+                                                               block--;
+                                                               prevItem = 
CACHE_BLOCK_ITEM_ADDR(channel,buffer,block);
+                                                       }
+                                                       while ((nextItem = 
CACHE_NEXT_ITEM(prevItem)) < item)
+                                                               prevItem = 
nextItem;
+                                                       // we must have found 
our item
+                                                       assert(nextItem==item);
+                                                       // now set the buffer
+                                                       
buffer->m_lastItemPositionW = CACHE_ITEM_POSITIONW(buffer,prevItem);
+                                                       
buffer->m_firstFreePositionW = positionW;
+                                                       buffer->m_lastTimestamp 
= buffer->m_firstTimestamp + prevItem->m_timeOffset;
+                                                       block = 
buffer->m_lastItemPositionW>>channel->m_positionToBlockShiftW;
+                                                       
buffer->lookup[block].m_offsetW = 
buffer->m_lastItemPositionW&channel->m_positionToOffsetMaskW;
+                                                       
buffer->lookup[block].m_timeOffset = prevItem->m_timeOffset;
                                                }
-                                               while ((nextItem = 
CACHE_NEXT_ITEM(prevItem)) < item)
-                                                       prevItem = nextItem;
-                                               // we must have found our item
-                                               assert(nextItem==item);
-                                               // now set the buffer
-                                               buffer->m_lastItemPositionW = 
CACHE_ITEM_POSITIONW(buffer,prevItem);
-                                               buffer->m_firstFreePositionW = 
positionW;
-                                               buffer->m_lastTimestamp = 
buffer->m_firstTimestamp + prevItem->m_timeOffset;
-                                               block = 
buffer->m_lastItemPositionW>>channel->m_positionToBlockShiftW;
-                                               buffer->lookup[block].m_offsetW 
= buffer->m_lastItemPositionW&channel->m_positionToOffsetMaskW;
-                                               
buffer->lookup[block].m_timeOffset = prevItem->m_timeOffset;
+                                               // set the channel
+                                               channel->m_lastBuffer = buffer;
+                                               if (buffer) {
+                                                       
channel->m_lastTimestamp = buffer->m_lastTimestamp;
+                                                       
channel->m_lastItemPositionW = buffer->m_lastItemPositionW;
+                                               }
                                        }
-                                       // set the channel
-                                       channel->m_lastBuffer = buffer;
-                                       if (buffer) {
-                                               channel->m_lastTimestamp = 
buffer->m_lastTimestamp;
-                                               channel->m_lastItemPositionW = 
buffer->m_lastItemPositionW;
-                                       }
                                }
                        }
                }
@@ -401,107 +419,120 @@
        channel = &entry->m_channelArray[id];
        if (length > channel->m_maxItemSizeB)
                return NULL;
-       if (!channel->m_lastBuffer) {
-               // no item in buffer, insert item at first position of first 
buffer
-               positionW = 0;
-               if ((buffer = channel->m_firstBuffer) == NULL) {
-                       buffer = channel->allocBuffer();
-                       channel->m_firstBuffer = buffer;
-               }
-       } else if (timestamp > channel->m_lastTimestamp) {
-               // this is the normal case: we are writing past lastest 
timestamp
-               buffer = channel->m_lastBuffer;
-               positionW = buffer->m_firstFreePositionW;
-       } else if (timestamp == channel->m_lastTimestamp) {
-               // common case, rewriting the last timestamp, just reuse the 
last position
-               buffer = channel->m_lastBuffer;
-               positionW = channel->m_lastItemPositionW;
+       if (timestamp == 0) {
+               // initial item, delete all buffers
+               channel->clear();
+               // and create initial item
+               item = NULL;
+               // we will allocate the memory, which is always pointer aligned 
=> compute size
+               // with NULL will give same result.
+               sizeW = CACHE_ITEM_SIZEW(item,length);
+               item = (CacheItem*)calloc(sizeW, 4);
+               item->m_sizeW = sizeW;
+               channel->initItem = item;
        } else {
-               // general case, write in the middle of the buffer, locate the 
timestamp
-               // (or the timestamp just after), clear this item and all 
future items,
-               // and write at that position
-               item = channel->findItemOrLater(timestamp, &buffer);
-               if (item == NULL) {
-                       // this should not happen
-                       return NULL;
+               if (!channel->m_lastBuffer) {
+                       // no item in buffer, insert item at first position of 
first buffer
+                       positionW = 0;
+                       if ((buffer = channel->m_firstBuffer) == NULL) {
+                               buffer = channel->allocBuffer();
+                               channel->m_firstBuffer = buffer;
+                       }
+               } else if (timestamp > channel->m_lastTimestamp) {
+                       // this is the normal case: we are writing past lastest 
timestamp
+                       buffer = channel->m_lastBuffer;
+                       positionW = buffer->m_firstFreePositionW;
+               } else if (timestamp == channel->m_lastTimestamp) {
+                       // common case, rewriting the last timestamp, just 
reuse the last position
+                       buffer = channel->m_lastBuffer;
+                       positionW = channel->m_lastItemPositionW;
+               } else {
+                       // general case, write in the middle of the buffer, 
locate the timestamp
+                       // (or the timestamp just after), clear this item and 
all future items,
+                       // and write at that position
+                       item = channel->findItemOrLater(timestamp, &buffer);
+                       if (item == NULL) {
+                               // this should not happen
+                               return NULL;
+                       }
+                       // this item will become the last one of this channel, 
clear any later buffer
+                       while ((next = buffer->m_next) != NULL) {
+                               buffer->m_next = next->m_next;
+                               free(next);
+                       }
+                       // no need to update the buffer, this will be done when 
the item is written
+                       positionW = CACHE_ITEM_POSITIONW(buffer,item);
                }

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to