示例#1
0
void GAFObject::step()
{
    m_showingFrame = m_currentFrame;

    if (!getIsAnimationRunning())
    {
        processAnimation();
        return;
    }

    if (m_sequenceDelegate && m_timeline)
    {
        const GAFAnimationSequence * seq = nullptr;
        if (!m_isReversed)
        {
            seq = m_timeline->getSequenceByLastFrame(m_currentFrame);
        }
        else
        {
            seq = m_timeline->getSequenceByFirstFrame(m_currentFrame + 1);
        }

        if (seq)
        {
            m_sequenceDelegate(this, seq->name);
        }
    }

    if (isCurrentFrameLastInSequence())
    {
        if (m_isLooped)
        {
            if (m_animationStartedNextLoopDelegate)
                m_animationStartedNextLoopDelegate(this);
        }
        else
        {
            setAnimationRunning(false, false);

            if (m_animationFinishedPlayDelegate)
                m_animationFinishedPlayDelegate(this);
        }
    }

    processAnimation();

    m_showingFrame = m_currentFrame;
    m_currentFrame = nextFrame();
}
void GAFAnimation::step()
{
	if (_sequenceDelegate && _asset)
	{
		GAFAnimationSequence * seq = _asset->getSequenceByLastFrame(_currentFrameIndex);
		if (seq)
		{
			_sequenceDelegate->onFinishSequence(dynamic_cast<GAFAnimatedObject*>(this), seq->name);
		}
	}
	
	if (_isLooped)
    {
        if (_currentFrameIndex >= _currentSequenceEnd)
        {
            _currentFrameIndex = _currentSequenceStart;
        }
    }
    else
    {
        if (_currentFrameIndex >= _currentSequenceEnd)
        {
            _isRunning = false;
            return;
        }
    }
    
    processAnimation();
    
    ++_currentFrameIndex;
}
bool GAFAnimation::setFrame(int aFrameIndex)
{
    if (aFrameIndex >= 0 && aFrameIndex < m_totalFrameCount)
    {
        _currentFrameIndex = aFrameIndex;
        processAnimation();
        return true;
    }
    return false;
}
示例#4
0
bool GAFObject::setFrame(uint32_t index)
{
    if (index < m_totalFrameCount)
    {
        m_showingFrame = m_currentFrame = index;
        processAnimation();
        return true;
    }
    return false;
}
示例#5
0
void SceneDisplayCallback(void) {

    // Setup viewing transformation
    glLoadIdentity();
    glScalef(scale, scale, scale);
    glTranslatef(translation[0], translation[1], 0.0);

    // Set projection transformation
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0, (GLfloat) GLUTwindow_width / (GLfloat) GLUTwindow_height, 0.1, 100.0);

    // Set camera transformation
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(translation[0], translation[1], translation[2]);
    glScalef(scale, scale, scale);
    glRotatef(rotation[0], 1.0, 0.0, 0.0);
    glRotatef(rotation[1], 0.0, 1.0, 0.0);
    glRotatef(rotation[2], 0.0, 0.0, 1.0);
    glTranslatef(-center[0], -center[1], -center[2]);

    // Clear window 
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Set lights
    glLightfv(GL_LIGHT0, GL_POSITION, difflight_position);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, difflight_color);

    static GLfloat light1_position[] = {-3.0, -4.0, -5.0, 0.0};
    glLightfv(GL_LIGHT1, GL_POSITION, light1_position);


    // Draw stuff 
    drawScene();
    drawDebugInfo();

    processAnimation();
    // Swap buffers 
    glutSwapBuffers();

}
示例#6
0
文件: cruise.cpp 项目: 33d/scummvm
void CruiseEngine::pauseEngine(bool pause) {
	Engine::pauseEngine(pause);

	if (pause) {
		// Draw the 'Paused' message
		drawSolidBox(64, 100, 256, 117, 0);
		drawString(10, 100, langString(ID_PAUSED), gfxModuleData.pPage00, itemColor, 300);
		gfxModuleData_flipScreen();

		_savedCursor = currentCursor;
		changeCursor(CURSOR_NOMOUSE);
	} else {
		processAnimation();
		flipScreen();
		changeCursor(_savedCursor);
	}

	gfxModuleData_addDirtyRect(Common::Rect(64, 100, 256, 117));
}
void ColladaShapeLoader::processAnimation(const domAnimation* anim, F32& maxEndTime, F32& minFrameTime)
{
   const char* sRGBANames[] =   { ".R", ".G", ".B", ".A", "" };
   const char* sXYZNames[] =    { ".X", ".Y", ".Z", "" };
   const char* sXYZANames[] =   { ".X", ".Y", ".Z", ".ANGLE" };
   const char* sLOOKATNames[] = { ".POSITIONX", ".POSITIONY", ".POSITIONZ", ".TARGETX", ".TARGETY", ".TARGETZ", ".UPX", ".UPY", ".UPZ", "" };
   const char* sSKEWNames[] =   { ".ROTATEX", ".ROTATEY", ".ROTATEZ", ".AROUNDX", ".AROUNDY", ".AROUNDZ", ".ANGLE", "" };
   const char* sNullNames[] =   { "" };

   for (S32 iChannel = 0; iChannel < anim->getChannel_array().getCount(); iChannel++) {

      // Get the animation elements: <channel>, <sampler>
      domChannel* channel = anim->getChannel_array()[iChannel];
      domSampler* sampler = daeSafeCast<domSampler>(channel->getSource().getElement());
      if (!sampler)
         continue;

      // Find the animation channel target
      daeSIDResolver resolver(channel, channel->getTarget());
      daeElement* target = resolver.getElement();
      if (!target) {
         daeErrorHandler::get()->handleWarning(avar("Failed to resolve animation "
            "target: %s", channel->getTarget()));
         continue;
      }
/*
      // If the target is a <source>, point it at the array instead
      // @todo:Only support targeting float arrays for now...
      if (target->getElementType() == COLLADA_TYPE::SOURCE)
      {
         domSource* source = daeSafeCast<domSource>(target);
         if (source->getFloat_array())
            target = source->getFloat_array();
      }
*/
      // Get the target's animation channels (create them if not already)
      if (!AnimData::getAnimChannels(target)) {
         animations.push_back(new AnimChannels(target));
      }
      AnimChannels* targetChannels = AnimData::getAnimChannels(target);

      // Add a new animation channel to the target
      targetChannels->push_back(new AnimData());
      channel->setUserData(targetChannels->last());
      AnimData& data = *targetChannels->last();

      for (S32 iInput = 0; iInput < sampler->getInput_array().getCount(); iInput++) {

         const domInputLocal* input = sampler->getInput_array()[iInput];
         const domSource* source = daeSafeCast<domSource>(input->getSource().getElement());
         if (!source)
            continue;

         // @todo:don't care about the input param names for now. Could
         // validate against the target type....
         if (dStrEqual(input->getSemantic(), "INPUT")) {
            data.input.initFromSource(source);
            // Adjust the maximum sequence end time
            maxEndTime = getMax(maxEndTime, data.input.getFloatValue((S32)data.input.size()-1));

            // Detect the frame rate (minimum time between keyframes)
            for (S32 iFrame = 1; iFrame < data.input.size(); iFrame++)
            {
               F32 delta = data.input.getFloatValue( iFrame ) - data.input.getFloatValue( iFrame-1 );
               if ( delta < 0 )
               {
                  daeErrorHandler::get()->handleError(avar("<animation> INPUT '%s' "
                     "has non-monotonic keys. Animation is unlikely to be imported correctly.", source->getID()));
                  break;
               }
               minFrameTime = getMin( minFrameTime, delta );
            }
         }
         else if (dStrEqual(input->getSemantic(), "OUTPUT"))
            data.output.initFromSource(source);
         else if (dStrEqual(input->getSemantic(), "IN_TANGENT"))
            data.inTangent.initFromSource(source);
         else if (dStrEqual(input->getSemantic(), "OUT_TANGENT"))
            data.outTangent.initFromSource(source);
         else if (dStrEqual(input->getSemantic(), "INTERPOLATION"))
            data.interpolation.initFromSource(source);
      }

      // Set initial value for visibility targets that were added automatically (in colladaUtils.cpp
      if (dStrEqual(target->getElementName(), "visibility"))
      {
         domAny* visTarget = daeSafeCast<domAny>(target);
         if (visTarget && dStrEqual(visTarget->getValue(), ""))
            visTarget->setValue(avar("%g", data.output.getFloatValue(0)));
      }

      // Ignore empty animations
      if (data.input.size() == 0) {
         channel->setUserData(0);
         delete targetChannels->last();
         targetChannels->pop_back();
         continue;
      }

      // Determine the number and offset the elements of the target value
      // targeted by this animation
      switch (target->getElementType()) {
         case COLLADA_TYPE::COLOR:        data.parseTargetString(channel->getTarget(), 4, sRGBANames);   break;
         case COLLADA_TYPE::TRANSLATE:    data.parseTargetString(channel->getTarget(), 3, sXYZNames);    break;
         case COLLADA_TYPE::ROTATE:       data.parseTargetString(channel->getTarget(), 4, sXYZANames);   break;
         case COLLADA_TYPE::SCALE:        data.parseTargetString(channel->getTarget(), 3, sXYZNames);    break;
         case COLLADA_TYPE::LOOKAT:       data.parseTargetString(channel->getTarget(), 3, sLOOKATNames); break;
         case COLLADA_TYPE::SKEW:         data.parseTargetString(channel->getTarget(), 3, sSKEWNames);   break;
         case COLLADA_TYPE::MATRIX:       data.parseTargetString(channel->getTarget(), 16, sNullNames);  break;
         case COLLADA_TYPE::FLOAT_ARRAY:  data.parseTargetString(channel->getTarget(), daeSafeCast<domFloat_array>(target)->getCount(), sNullNames); break;
         default:                         data.parseTargetString(channel->getTarget(), 1, sNullNames);   break;
      }
   }

   // Process child animations
   for (S32 iAnim = 0; iAnim < anim->getAnimation_array().getCount(); iAnim++)
      processAnimation(anim->getAnimation_array()[iAnim], maxEndTime, minFrameTime);
}
void ColladaShapeLoader::enumerateScene()
{
   // Get animation clips
   Vector<const domAnimation_clip*> animationClips;
   for (S32 iClipLib = 0; iClipLib < root->getLibrary_animation_clips_array().getCount(); iClipLib++) {
      const domLibrary_animation_clips* libraryClips = root->getLibrary_animation_clips_array()[iClipLib];
      for (S32 iClip = 0; iClip < libraryClips->getAnimation_clip_array().getCount(); iClip++)
         appSequences.push_back(new ColladaAppSequence(libraryClips->getAnimation_clip_array()[iClip]));
   }

   // Process all animations => this attaches animation channels to the targeted
   // Collada elements, and determines the length of the sequence if it is not
   // already specified in the Collada <animation_clip> element
   for (S32 iSeq = 0; iSeq < appSequences.size(); iSeq++) {
      ColladaAppSequence* appSeq = dynamic_cast<ColladaAppSequence*>(appSequences[iSeq]);
      F32 maxEndTime = 0;
      F32 minFrameTime = 1000.0f;
      for (S32 iAnim = 0; iAnim < appSeq->getClip()->getInstance_animation_array().getCount(); iAnim++) {
         domAnimation* anim = daeSafeCast<domAnimation>(appSeq->getClip()->getInstance_animation_array()[iAnim]->getUrl().getElement());
         if (anim)
            processAnimation(anim, maxEndTime, minFrameTime);
      }
      if (appSeq->getEnd() == 0)
         appSeq->setEnd(maxEndTime);

      // Collada animations can be stored as sampled frames or true keyframes. For
      // sampled frames, use the same frame rate as the DAE file. For true keyframes,
      // resample at a fixed frame rate.
      appSeq->fps = mClamp(1.0f / minFrameTime + 0.5f, TSShapeLoader::MinFrameRate, TSShapeLoader::MaxFrameRate);
   }

   // First grab all of the top-level nodes
   Vector<domNode*> sceneNodes;
   for (S32 iSceneLib = 0; iSceneLib < root->getLibrary_visual_scenes_array().getCount(); iSceneLib++) {
      const domLibrary_visual_scenes* libScenes = root->getLibrary_visual_scenes_array()[iSceneLib];
      for (S32 iScene = 0; iScene < libScenes->getVisual_scene_array().getCount(); iScene++) {
         const domVisual_scene* visualScene = libScenes->getVisual_scene_array()[iScene];
         for (S32 iNode = 0; iNode < visualScene->getNode_array().getCount(); iNode++)
            sceneNodes.push_back(visualScene->getNode_array()[iNode]);
      }
   }

   // Set LOD option
   bool singleDetail = true;
   switch (ColladaUtils::getOptions().lodType)
   {
      case ColladaUtils::ImportOptions::DetectDTS:
         // Check for a baseXX->startXX hierarchy at the top-level, if we find
         // one, use trailing numbers for LOD, otherwise use a single size
         for (S32 iNode = 0; singleDetail && (iNode < sceneNodes.size()); iNode++) {
            domNode* node = sceneNodes[iNode];
            if (dStrStartsWith(_GetNameOrId(node), "base")) {
               for (S32 iChild = 0; iChild < node->getNode_array().getCount(); iChild++) {
                  domNode* child = node->getNode_array()[iChild];
                  if (dStrStartsWith(_GetNameOrId(child), "start")) {
                     singleDetail = false;
                     break;
                  }
               }
            }
         }
         break;

      case ColladaUtils::ImportOptions::SingleSize:
         singleDetail = true;
         break;

      case ColladaUtils::ImportOptions::TrailingNumber:
         singleDetail = false;
         break;
         
      default:
         break;
   }

   ColladaAppMesh::fixDetailSize( singleDetail, ColladaUtils::getOptions().singleDetailSize );

   // Process the top level nodes
   for (S32 iNode = 0; iNode < sceneNodes.size(); iNode++) {
      ColladaAppNode* node = new ColladaAppNode(sceneNodes[iNode], 0);
      if (!processNode(node))
         delete node;
   }

   // Make sure that the scene has a bounds node (for getting the root scene transform)
   if (!boundsNode)
   {
      domVisual_scene* visualScene = root->getLibrary_visual_scenes_array()[0]->getVisual_scene_array()[0];
      domNode* dombounds = daeSafeCast<domNode>( visualScene->createAndPlace( "node" ) );
      dombounds->setName( "bounds" );
      ColladaAppNode *appBounds = new ColladaAppNode(dombounds, 0);
      if (!processNode(appBounds))
         delete appBounds;
   }
}
void GAFAnimation::step()
{
    if (! m_isReversed)
    {
        if (_currentFrameIndex < m_currentSequenceStart)
        {
            _currentFrameIndex = m_currentSequenceStart;
        }

        if (_sequenceDelegate && m_asset)
        {
            const GAFAnimationSequence * seq = m_asset->getSequenceByLastFrame(_currentFrameIndex);
            if (seq)
            {
                _sequenceDelegate->onFinishSequence(dynamic_cast<GAFAnimatedObject*>(this), seq->name);
            }
        }

        if (_currentFrameIndex >= m_currentSequenceEnd)
        {
            if (m_isLooped)
            {
                _currentFrameIndex = m_currentSequenceStart;
                
                if (m_animationPlaybackDelegate)
                {
                    m_animationPlaybackDelegate->onAnimationStartedNextLoopDelegate(this);
                }
            }
            else
            {
                setAnimationRunning(false);

                if (m_animationPlaybackDelegate)
                {
                    m_animationPlaybackDelegate->onAnimationFinishedPlayDelegate(this);
                }

                return;
            }
        }

        processAnimation();

        ++_currentFrameIndex;
    }
    else
    {
        // If switched to reverse after final frame played
        if (_currentFrameIndex >= m_currentSequenceEnd)
        {
            _currentFrameIndex = m_currentSequenceEnd - 1;
        }

        if (_sequenceDelegate && m_asset)
        {
            const GAFAnimationSequence * seq = m_asset->getSequenceByFirstFrame(_currentFrameIndex + 1);
            if (seq)
            {
                _sequenceDelegate->onFinishSequence(dynamic_cast<GAFAnimatedObject*>(this), seq->name);
            }
        }

        if (_currentFrameIndex < m_currentSequenceStart)
        {
            if (m_isLooped)
            {
                _currentFrameIndex = m_currentSequenceEnd - 1;

                if (m_animationPlaybackDelegate)
                {
                    m_animationPlaybackDelegate->onAnimationStartedNextLoopDelegate(this);
                }
            }
            else
            {
                setAnimationRunning(false);

                if (m_animationPlaybackDelegate)
                {
                    m_animationPlaybackDelegate->onAnimationFinishedPlayDelegate(this);
                }

                return;
            }
        }

        processAnimation();

        --_currentFrameIndex;
    }
}
示例#10
0
void CruiseEngine::mainLoop() {
	//int32 t_start,t_left;
	//uint32 t_end;
	//int32 q=0;                     /* Dummy */
	int16 mouseX, mouseY;
	int16 mouseButton;

	int enableUser = 0;

	strcpy(nextOverlay, "");
	strcpy(lastOverlay, "");
	strcpy(cmdLine, "");

	currentActiveMenu = -1;
	autoMsg = -1;
	linkedRelation = 0;
	main21 = 0;
	main22 = 0;
	userWait = 0;
	autoTrack = false;

	initAllData();

	playerDontAskQuit = 0;
	int quitValue2 = 1;
	int quitValue = 0;

	if (ConfMan.hasKey("save_slot"))
		loadGameState(ConfMan.getInt("save_slot"));

	do {
		// Handle frame delay
		uint32 currentTick = g_system->getMillis();

		if (!bFastMode) {
			// Delay for the specified amount of time, but still respond to events
			bool skipEvents = false;

			do {
				g_system->delayMillis(10);
				currentTick = g_system->getMillis();

				if (!skipEvents)
					skipEvents = manageEvents();

				if (playerDontAskQuit)
					break;

				_vm->getDebugger()->onFrame();
			} while (currentTick < lastTick + _gameSpeed);
		} else {
			manageEvents();

			if (currentTick >= (lastTickDebug + 10)) {
				lastTickDebug = currentTick;
				_vm->getDebugger()->onFrame();
			}
		}
		if (playerDontAskQuit)
			break;

		lastTick = g_system->getMillis();

		// Handle switchover in game speed after intro
		if (!_speedFlag && canLoadGameStateCurrently()) {
			_speedFlag = true;
			_gameSpeed = GAME_FRAME_DELAY_2;
		}

		// Handle the next frame

//		frames++;
//      t_start=Osystem_GetTicks();

//      readKeyboard();

		bool isUserWait = userWait != 0;
		playerDontAskQuit = processInput();
		if (playerDontAskQuit)
			break;

		if (enableUser) {
			userEnabled = 1;
			enableUser = 0;
		}

		if (userDelay && !userWait) {
			userDelay--;
			continue;
		}

		if (isUserWait & !userWait) {
			// User waiting has ended
			changeScriptParamInList(-1, -1, &procHead, 9999, 0);
			changeScriptParamInList(-1, -1, &relHead, 9999, 0);

			// Disable any mouse click used to end the user wait
			currentMouseButton = 0;
		}

		// FIXME: I suspect that the original game does multiple script executions between game frames; the bug with
		// Raoul appearing when looking at the book is being there are 3 script iterations separation between the
		// scene being changed to the book, and the Raoul actor being frozen/disabled. This loop is a hack to ensure
		// that when a background changes, a few extra script executions are done
		bool bgChanged;
		int numIterations = 1;

		while (numIterations-- > 0) {
			bgChanged = backgroundChanged[masterScreen];
		
			manageScripts(&relHead);
			manageScripts(&procHead);

			removeFinishedScripts(&relHead);
			removeFinishedScripts(&procHead);

			if (!bgChanged && backgroundChanged[masterScreen]) {
				bgChanged = true;
				numIterations += 2;
			}
		}

		processAnimation();

		if (remdo) {
			// ASSERT(0);
			/*    main3 = 0;
			 * var24 = 0;
			 * var23 = 0;
			 *
			 * freeStuff2(); */
		}

		if (cmdLine[0]) {
			ASSERT(0);
			/*        redrawStrings(0,&cmdLine,8);

			        waitForPlayerInput();

			        cmdLine = 0; */
		}

		if (displayOn) {
			if (doFade)
				PCFadeFlag = 0;

			/*if (!PCFadeFlag)*/
			mainDraw(userWait);
			flipScreen();

			if (userEnabled && !userWait && !autoTrack) {
				if (currentActiveMenu == -1) {
					static int16 oldMouseX = -1;
					static int16 oldMouseY = -1;

					getMouseStatus(&main10, &mouseX, &mouseButton, &mouseY);

					if (mouseX != oldMouseX || mouseY != oldMouseY) {
						int objectType;
						int newCursor1;
						int newCursor2;

						oldMouseX = mouseX;
						oldMouseY = mouseY;

						objectType = findObject(mouseX, mouseY, &newCursor1, &newCursor2);

						if (objectType == 9) {
							changeCursor(CURSOR_EXIT);
						} else if (objectType != -1) {
							changeCursor(CURSOR_MAGNIFYING_GLASS);
						} else {
							changeCursor(CURSOR_WALK);
						}
					}
				} else {
					changeCursor(CURSOR_NORMAL);
				}
			} else {
				changeCursor(CURSOR_NORMAL);
			}

			if (userWait == 1) {
				// Waiting for press - original wait loop has been integrated into the
				// main event loop
				continue;
			}

			// wait for character to finish auto track
			if (autoTrack) {
				if (isAnimFinished(narratorOvl, narratorIdx, &actorHead, ATP_MOUSE)) {
					if (autoMsg != -1) {
						freezeCell(&cellHead, autoOvl, autoMsg, 5, -1, 9998, 0);

						char* pText = getText(autoMsg, autoOvl);

						if (strlen(pText))
							userWait = 1;
					}

					changeScriptParamInList(-1, -1, &relHead, 9998, 0);
					autoTrack = false;
					enableUser = 1;
				} else {
					userEnabled = false;
				}
			} else if (autoMsg != -1) {
				removeCell(&cellHead, autoOvl, autoMsg, 5, masterScreen);
				autoMsg = -1;
			}
		} else {
			// Keep ScummVM being responsive even when displayOn is false
			g_system->updateScreen();
		}

	} while (!playerDontAskQuit && quitValue2 && quitValue != 7);

	// Free data
	removeAllScripts(&relHead);
	removeAllScripts(&procHead);
	resetActorPtr(&actorHead);
	freeOverlayTable();
	closeCnf();
	closeBase();
	resetFileEntryRange(0, NUM_FILE_ENTRIES);
	freeObjectList(&cellHead);
	freeBackgroundIncrustList(&backgroundIncrustHead);
}