void MeshLoader_v1::ReadSkelAnim(MeshPtr mesh, DataStreamPtr & stream) { Skeleton * skel = mesh->GetSkeleton(); int version = -1; stream->Read(&version, sizeof (int)); d_assert (version == K_SkelAnim_Version); char name[128]; stream->Read(name, 128); Animation * anim = mesh->CreateAnimation(name); int numAnims = 0; stream->Read(&numAnims, sizeof(int)); for (int i = 0; i < numAnims; ++i) { int boneId, count; stream->Read(&boneId, sizeof(int)); stream->Read(&count, sizeof(int)); if (count == 0) continue; SkeletonAnimation * skel_anim; skel_anim = anim->CreateSkeletonAnimation(boneId); KeyFrame * kf; float time; Vec3 trans; Quat rotate; Vec3 scale; for (int i = 0; i < count; ++i) { stream->Read(&time, sizeof(float)); stream->Read(&trans, sizeof(float) * 3); stream->Read(&rotate, sizeof(float) * 4); stream->Read(&scale, sizeof(float) * 3); kf = skel_anim->CreateKeyFrame(); kf->SetTime(time); kf->SetTranslate(trans); kf->SetRotation(rotate); kf->SetScale(scale); } } anim->_calcuLength(); }
// ValidateItemLayout void SlideShowPlaylist::ValidateItemLayout() { int64 duration = Value(PROPERTY_DURATION, (int64)0); if (duration == 0) return; int64 transitionDuration = Value(PROPERTY_TRANSITION_DURATION, (int64)0); // TODO: transition mode... int32 count = CountItems(); BList managedItems; int64 minDuration = 0; int64 minItemDuration = transitionDuration * 3; int64 fixedItemsDuration = 0; int64 maxDuration = 0; int32 variableItemCount = 0; for (int32 i = 0; i < count; i++) { PlaylistItem* item = ItemAtFast(i); if (item->Track() > 1) // not a "managed" item continue; managedItems.AddItem(item); if (item->HasMaxDuration()) { int64 maxItemDuration = item->MaxDuration(); minDuration += maxItemDuration; fixedItemsDuration += maxItemDuration; if (minItemDuration > maxItemDuration) minItemDuration = maxItemDuration; } else { minDuration += 3 * transitionDuration; variableItemCount++; } maxDuration += item->MaxDuration(); } count = managedItems.CountItems(); if (count == 0) return; if (duration < minDuration) duration = minDuration; if (duration > maxDuration) duration = maxDuration; // limit transition duration to 1/3 of the minimum item duration int64 maxTransitionDuration = minItemDuration / 3; if (transitionDuration > maxTransitionDuration) transitionDuration = maxTransitionDuration; int64 variableItemsDuration = duration - fixedItemsDuration + transitionDuration * (count - variableItemCount); int64 startFrame = 0; int64 lastVariableStartFrame = 0; int32 variableItemIndex = 0; for (int32 i = 0; i < count; i++) { PlaylistItem* item = (PlaylistItem*)managedItems.ItemAtFast(i); // overlapping items item->SetClipOffset(0); item->SetTrack(i & 1); int64 nextStartFrame; if (item->HasMaxDuration()) { nextStartFrame = startFrame + item->MaxDuration() - transitionDuration; } else { variableItemIndex++; int64 nextVariableStartFrame = (variableItemsDuration - transitionDuration) * variableItemIndex / variableItemCount; nextStartFrame = startFrame + nextVariableStartFrame - lastVariableStartFrame; lastVariableStartFrame = nextVariableStartFrame; } item->SetStartFrame(startFrame); item->SetDuration(nextStartFrame - startFrame + transitionDuration); startFrame = nextStartFrame; // transition PropertyAnimator* animator = item->AlphaAnimator(); if (!animator) continue; AutoNotificationSuspender _(animator); // remove all keyframes to get a clean start animator->MakeEmpty(); KeyFrame* first = animator->InsertKeyFrameAt(0LL); KeyFrame* last = animator->InsertKeyFrameAt(item->Duration() - 1); if (!first || !last) continue; first->SetScale(1.0); last->SetScale(1.0); // transition in top items if (transitionDuration > 0 && !(i & 1)) { // item on first track, animated opacity property if (i > 0) { // fade in KeyFrame* key = animator->InsertKeyFrameAt(transitionDuration); key->SetScale(1.0); first->SetScale(0.0); } if (i < count - 1) { // fade out KeyFrame* key = animator->InsertKeyFrameAt( item->Duration() - 1 - transitionDuration); key->SetScale(1.0); last->SetScale(0.0); } } } }
// _LayoutBackgroundSound status_t CollectingPlaylist::_LayoutBackgroundSound(const ServerObjectManager* library) { // find the background sound clip, if we are supposed to have one Clip* soundClip = NULL; BString soundClipID = SoundClipID(); if (soundClipID.Length() > 0) { soundClip = dynamic_cast<Clip*>(library->FindObject( soundClipID.String())); if (!soundClip) { print_error("CollectingPlaylist::_LayoutBackgroundSound() - " "didn't background sound clip: %s (ignoring)\n", soundClipID.String()); return B_OK; } } else { // no background sound configured return B_OK; } float volume = Value(PROPERTY_BACKGROUND_SOUND_VOLUME, (float)1.0); uint64 duration = Duration(); uint64 startFrame = 0; while (startFrame < duration) { ClipPlaylistItem* item = new (nothrow) ClipPlaylistItem(soundClip); if (!item) { print_error("CollectingPlaylist::_LayoutBackgroundSound() - " "no memory to create ClipPlaylistItem\n"); return B_NO_MEMORY; } uint64 itemDuration = soundClip->Duration(); uint64 maxItemDuration = duration - startFrame; if (startFrame == 0 && itemDuration >= maxItemDuration) { // one item as long as first track or longer // cut off itemDuration = maxItemDuration; // fade in + fade out PropertyAnimator* animator = item->AlphaAnimator(); if (animator) { // remove all keyframes to get a clean start animator->MakeEmpty(); KeyFrame* first = animator->InsertKeyFrameAt(0LL); KeyFrame* fadeEnd = animator->InsertKeyFrameAt(3); KeyFrame* fadeStart = animator->InsertKeyFrameAt( itemDuration - 4); KeyFrame* last = animator->InsertKeyFrameAt(itemDuration - 1); if (!first || !fadeEnd || !fadeStart || !last) { delete item; print_error("CollectingPlaylist::_LayoutBackgroundSound()" " - no memory to add fade keyframes\n"); return B_NO_MEMORY; } first->SetScale(0.0); fadeEnd->SetScale(volume); fadeStart->SetScale(volume); last->SetScale(0.0); } } else if (startFrame == 0) { // first item, more to come // fade in PropertyAnimator* animator = item->AlphaAnimator(); if (animator) { // remove all keyframes to get a clean start animator->MakeEmpty(); KeyFrame* first = animator->InsertKeyFrameAt(0LL); KeyFrame* fadeEnd = animator->InsertKeyFrameAt(3); KeyFrame* last = animator->InsertKeyFrameAt(itemDuration - 1); if (!first || !fadeEnd || !last) { delete item; print_error("CollectingPlaylist::_LayoutBackgroundSound()" " - no memory to add fade keyframes\n"); return B_NO_MEMORY; } first->SetScale(0.0); fadeEnd->SetScale(volume); last->SetScale(volume); } } else if (itemDuration >= maxItemDuration) { // last item // cut off itemDuration = maxItemDuration; // fade out PropertyAnimator* animator = item->AlphaAnimator(); if (animator) { // remove all keyframes to get a clean start animator->MakeEmpty(); KeyFrame* first = animator->InsertKeyFrameAt(0LL); KeyFrame* fadeStart = animator->InsertKeyFrameAt( itemDuration - 4); KeyFrame* last = animator->InsertKeyFrameAt(itemDuration - 1); if (!first || !fadeStart || !last) { delete item; print_error("CollectingPlaylist::_LayoutBackgroundSound()" " - no memory to add fade keyframes\n"); return B_NO_MEMORY; } first->SetScale(volume); fadeStart->SetScale(volume); last->SetScale(0.0); } } else { // any remaining item PropertyAnimator* animator = item->AlphaAnimator(); if (animator) { // remove all keyframes to get a clean start animator->MakeEmpty(); KeyFrame* first = animator->InsertKeyFrameAt(0LL); if (!first) { delete item; print_error("CollectingPlaylist::_LayoutBackgroundSound()" " - no memory to add fade keyframes\n"); return B_NO_MEMORY; } first->SetScale(volume); } } item->SetStartFrame(startFrame); item->SetDuration(itemDuration); item->SetTrack(1); if (!AddItem(item)) { delete item; print_error("CollectingPlaylist::_LayoutBackgroundSound() - " "no memory to add ClipPlaylistItem\n"); return B_NO_MEMORY; } startFrame += itemDuration; } return B_OK; }