[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21599] branches/itasc: iTaSC: negative frame handling: add special item for rest pose in cache.

Benoit Bolsee benoit.bolsee at online.be
Wed Jul 15 19:11:08 CEST 2009


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. @@




More information about the Bf-blender-cvs mailing list