Accepted: IK support in Ogre's skeletal animation

Threads related to Google Summer of Code
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »


I am working on the animations and pseudo code, but i have been using this syntax on my code blendParameter("speed", 1)

so following your ninja code we would have:

Code: Select all


a.registerParameter("speed", n.speed);
a.setParameter("crouch", 2);
a.blendParameter("speed", 1);

Also thought of using blendPropriety(...), are there any guidelines and naming conventions for OGRE API creation? If there are, it is best to follow them.
i totally agree with those changes, as for OGRE standards: I am very new to ogre, i will not comment. blendPropriety() sounds good.
PS: Found this code snippet useful to undertand how to control indevidual bones: http://www.ogre3d.org/wiki/index.php/Ma ... llingBones Smile
yeah i know it. as you could see, i used manual control here(though this way seriouslly sucks, I will comment on that later):

Code: Select all

for (int j = 0; j < 18; j++)
      {
         bi.peekNext()->setManuallyControlled(true);
         bi.peekNext()->setOrientation(r[j]);
         
         bi.moveNext();
      };
Anyway, I should have the animations and code by next Friday.
Really appreciate. no hurry though. Will take time to go to a point when i can use code with blendParameter() in it:). What i could use at this stage is skeleton with nice animatios of at least run AND walk in it. Would be a real help. DanMD what you do is really useful for me. the same to you KungFooMasta. thx
@jarek108: imho, r[x] values are local Orientation, rather than derived ones, so you have to compare them with "Bone->getOrientation();".
nothing like an advice from my mentor:). works perfect now. thx
(you'll have to go in Sinbad direction, handling multiple skeleton is the wrong way.)

About orientation problem (your code does not seems to sum them), but anyway you'll have to read NodeAnimationTrack::applyToNode() code to fully see how to apply multiples Transform on a nodes sequentially.
so true... like i wrote to you in private email, even before Sindbad mentioned it: i really hate the to be on the level of skeletons and feel it should be on a level of NodeTracks. the code with:

Code: Select all

 TimeIndex timeIndex = a->_getTimeIndex(time);
Ogre::Animation::NodeTrackList l = a->_getNodeTrackList();
Ogre::Animation::NodeTrackList::const_iterator i;

int j=0;
for (i = l.begin(); i != l.end(); ++i)
{

TransformKeyFrame kf(i->second, timeIndex.getTimePos());

r[j++] = kf.getRotation()
}; 
was based on NodeAnimationTrack::applyToNode() code but something was wrong with it(and i do not think it was a matter of adding them up, they were just zero all the time or sth, it was like more basic mistake), did n`t want to waste more hours back then to play with it, but i`ll return to that later if no one "wise";) will help me here. right now i have a code that does the same thing(create matrix of rotation quaternions in a given animation moment) on a level of skeletons , will go to NodeTracks when i know how.


right now i will spend my time on learning CEGUI and input in ogre to be able to create useful simple tools for blending. i will also need them to test my system as it grows. will keep you informed.
User avatar
Injector
Gremlin
Posts: 174
Joined: Wed Jan 21, 2004 2:42 pm
Location: Frankfurt, Germany

Post by Injector »

I could provide you with a mesh (+skeleton) having lots of animations (including walk and run cycles). PM me, if you are interested. :)
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

already discussed this with my mentor. i have exam sesion until about the 18th june, and i will not be able to put a lot of my time in communication, but please write all you feel can help this project. i already recived some nice propositions both private and on forums thanks for that. i will look in to that when i can and put 100% horse power into project after exams. thx guys
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

OK, so this is a first vision of animation editor for my GSoC project.
I'm new to cegui and i have tons of beginner`s problems. some are not solved so stuff is quite buggy. sorry. i give it just to show where i`m going and that I'm actually doing something;) and to establish ground for discussion.
few remarks before you run it:
1. what it does:
so far not much. lets you select a mesh, two animations(small models to the sides), and gives you result of their combination given joint weights.

2. controls:
left, right = rotation
up, down = scale models
to change the mesh + animations click buttons...

3. IMPORTANT. bugs and limitations.
as i said before they are serious.

a). i have problems with resetList() method, it crashes the system if i apply it so i do NOT clear combo boxes after changing the mesh. result is that new animations for selected models are just added after the old ones so the list is getting big and if you try to select animation name from old mesh you kill the program. bad. i know. have to wait until i discover how to clean combo box without a crash
b). i do not know how to make a window with joint names and editable weights so for now these are just hard coded to work with robot.mesh(first half is for lower body the other for upper i believe). if you use other mesh it will work but it will always take half joints from 1st and half from 2nd animation. the result normally sucks.
Conclusion from a) + b) = you can check other meshes but i`d only play with robot for now.
c). so far it only works with animations that have a mesh so i excluded all others from resources.
d). there is a mistake in my addAnimations method. i apply operation for all the joints but looks like i miss some info from original animations. works ok for most but if you apply die animation to a robot for example you will see that some main rotation/transition coping is not working well. will look soon into that.
e)when you exit it crushes:). sorry again:). i was always leaving anyway when this happened so it had low priority, did n`t investigate it yet.

4. where I'm going:
i want to have editor for building and traversing the tree(in a window where a combobox is right now) to build animation tree like in the project discription. one will be able to build a hierarchy of animations play with parameters to see results "on line" and save stuff for external usage when finished.
first steps:
- eliminate bugs(any ideas about resetList crush??).
- make joint weight editor(if anyone knows how to do window with list of editable real elements, please let me know, code examples very welcome)
- save/load weights + everything else
- edition of tree

Thanks to KungFooMasta and my mentor Tuan Kuranes for help and tips.

Code: Select all

#include "StdAfx.h"
using namespace std;

string debug;
void displayDebug()
{
		OverlayElement* guiDebug = OverlayManager::getSingleton().getOverlayElement("Core/BestFps");
		guiDebug->setCaption(debug);
};


//anim.cpp
void addAnimations(Entity *ent1, Entity *ent2, Entity *result)
{

	int joints = ent1->getSkeleton()->getNumBones();

	string *s = new string[joints];
	Quaternion *r  = new Quaternion[joints];
	Vector3 *p  = new Vector3[joints];
	

	//float angle[108];
	;

	Skeleton *skel = ent1->getSkeleton();//walk
	Skeleton::BoneIterator bi = skel->getBoneIterator();
	for (int j = 0; j < joints/2; j++)
	{
		r[j] = bi.peekNext()->getOrientation();
		p[j] = bi.peekNext()->getPosition();
		s[j] = bi.peekNext()->getName();

		bi.moveNext();
	};

	skel = ent2->getSkeleton();//idle
	bi = skel->getBoneIterator();
	for (int j = 0; j < joints/2; j++){bi.moveNext();};
	for (int j = joints/2; j < joints; j++)
	{
		r[j] =  bi.peekNext()->getOrientation();
		p[j] = bi.peekNext()->getPosition();
		s[j] = bi.peekNext()-> getName();

		bi.moveNext();
	};

	skel = result->getSkeleton();
	bi = skel->getBoneIterator();
	for (int j = 0; j < joints; j++)
	{
		bi.peekNext()->setManuallyControlled(true);
		bi.peekNext()->setOrientation(r[j]);
		bi.peekNext()->setPosition(p[j]);

		
		//calculate diffrence angle
		//q = q.Inverse() * r[j];
		//angle[j] = 2*Math::ACos(q.w).valueDegrees();*/

		bi.moveNext();
	};

	delete[] s;
	delete[] r;
	delete[] p;
};





//convert.cpp
#define LOOKNFEEL "TaharezLook"
	#define BRUSH "ClientBrush"
#define SELECTED_COLOR CEGUI::colour(0.0, 1, 0.0)
	#define BASIC_COLOR CEGUI::colour(1.0, 1.0, 1.0)


CEGUI::MouseButton convertOgreButtonToCegui(int buttonID)
{
	using namespace OIS; 

   switch (buttonID)
   {
   case OIS::MB_Left:
       return CEGUI::LeftButton;
   case OIS::MB_Right:
       return CEGUI::RightButton;
   case OIS::MB_Middle:
       return CEGUI::MiddleButton;
// Not sure what to do with this one...
//   case MouseEvent::BUTTON3_MASK:
//       return CEGUI::X1Button;
   default:
       return CEGUI::LeftButton;
   }
}



	

















//listener
class GuiFrameListener : public ExampleFrameListener,  public OIS::MouseListener, public OIS::KeyListener
{ 
private:
	AnimationState *mAnimationState1, *mAnimationState2;

	Entity *model1, *model2, *resultModel;
	SceneNode *node1, *node2, *node3;

	SceneManager* mSceneMgr;
	

	CEGUI::OgreCEGUIRenderer* mGUIRenderer;
	CEGUI::System* mGUISystem;
	CEGUI::Window* mEditorGuiSheet;

	bool mShutdownRequested;

public:
	GuiFrameListener(RenderWindow* win, Camera* cam, SceneManager* _mSceneMgr):
    ExampleFrameListener(win, cam, true, true), 
        mShutdownRequested(false),
		mSceneMgr(_mSceneMgr),
		mGUIRenderer(0),
		mGUISystem(0),
		mEditorGuiSheet(0)
	{
		mMouse->setEventCallback( this );
		mKeyboard->setEventCallback( this );

		setupGUI();

		//create mesh points
		node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Anim Node 1", Vector3(-150.0, 0.0, 0.0));
		node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Result Node", Vector3(150.0, 0.0, 0.0));
		node3 = mSceneMgr->getRootSceneNode()->createChildSceneNode("Anim Node 2", Vector3(0.0, 0.0, 0.0));		
	
		node2->yaw(Ogre::Radian(-0.2));
		node3->scale(1.3, 1.3, 1.3);
		
		modelSelection("robot.mesh");

		//animation setup
		mAnimationState1 = model1->getAnimationState("Walk");
		mAnimationState1 -> setEnabled(true);
		mAnimationState1 -> setLoop(true);

		mAnimationState2 = model2->getAnimationState("Idle");
		mAnimationState2 -> setEnabled(true);
		mAnimationState2 -> setLoop(true);

		//animationBoxUpdate();
	};
	
	~GuiFrameListener()
	{
	if(mEditorGuiSheet)
	   {
		   CEGUI::WindowManager::getSingleton().destroyWindow(mEditorGuiSheet);
	   }
	   if(mGUISystem)
	   {
		   delete mGUISystem;
		   mGUISystem = 0;
	   }
	   if(mGUIRenderer)
	   {
		   delete mGUIRenderer;
		   mGUIRenderer = 0;
	   }
	}
	void handleKeyboard(float time)
	{
		float scaleUp = 1 + time;
		float scaleDown = 1 - time;

		float turn = 2 * time;

		if (mKeyboard->isKeyDown(OIS::KC_UP)) 
		{
			node1->scale(scaleUp, scaleUp, scaleUp) ;
			node2->scale(scaleUp, scaleUp, scaleUp) ;
			node3->scale(scaleUp, scaleUp, scaleUp) ;
		};

		if (mKeyboard->isKeyDown(OIS::KC_DOWN)) 
		{
			node1->scale(scaleDown, scaleDown, scaleDown) ;
			node2->scale(scaleDown, scaleDown, scaleDown) ;
			node3->scale(scaleDown, scaleDown, scaleDown) ;
		};


		if (mKeyboard->isKeyDown(OIS::KC_RIGHT))
		{
			node1->yaw(Ogre::Radian(turn));
			node2->yaw(Ogre::Radian(turn));
			node3->yaw(Ogre::Radian(turn));
		}

		if (mKeyboard->isKeyDown(OIS::KC_LEFT))
		{
			node1->yaw(Ogre::Radian(-turn));
			node2->yaw(Ogre::Radian(-turn));
			node3->yaw(Ogre::Radian(-turn));
		}
	}

	void modelSelection(string name)
	{
		if (model1) mSceneMgr->destroyEntity("model1");
		if (model2) mSceneMgr->destroyEntity("model2");
		if (resultModel) mSceneMgr->destroyEntity("resultModel");

		model1 = mSceneMgr->createEntity("model1", name);
		node1->attachObject(model1);
		if (model1->getAllAnimationStates())
		{
			mAnimationState1 = model1->getAllAnimationStates()->getAnimationStateIterator().getNext();
			mAnimationState1 -> setEnabled(true);
			mAnimationState1 -> setLoop(true);
		} else mAnimationState1 = 0;
		
		model2 = mSceneMgr->createEntity("model2", name);	
		node2->attachObject(model2);
		if (model1->getAllAnimationStates())
		{
			mAnimationState2 = model2->getAllAnimationStates()->getAnimationStateIterator().getNext();
			mAnimationState2 -> setEnabled(true);
			mAnimationState2 -> setLoop(true);
		} else mAnimationState2 = 0;

		resultModel = mSceneMgr->createEntity("resultModel", name);
		node3->attachObject(resultModel);

		animationBoxUpdate();
		jointBoxUpdate();
	}

	//CEGUI communication
	bool handleMeshSelect(const CEGUI::EventArgs& e)
	{
		using namespace CEGUI;

		const WindowEventArgs& wEventArgs = static_cast<const WindowEventArgs&>(e);
		ListboxItem* item = static_cast<Combobox*>(wEventArgs.window)->getSelectedItem();

		if (! item)
			return false;

		modelSelection(item->getText().c_str());

		return true;
	}


	bool handleModel1Select(const CEGUI::EventArgs& e)
	{
		using namespace CEGUI;

		const WindowEventArgs& wEventArgs = static_cast<const WindowEventArgs&>(e);
		ListboxItem* item = static_cast<Combobox*>(wEventArgs.window)->getSelectedItem();

		if (! item)
			return false;

		mAnimationState1 = model1->getAnimationState(item->getText().c_str());
		mAnimationState1 -> setEnabled(true);
		mAnimationState1 -> setLoop(true);

		return true;
	}

	bool handleModel2Select(const CEGUI::EventArgs& e)
	{
		using namespace CEGUI;

		const WindowEventArgs& wEventArgs = static_cast<const WindowEventArgs&>(e);
		ListboxItem* item = static_cast<Combobox*>(wEventArgs.window)->getSelectedItem();

		if (! item)
			return false;

		mAnimationState2 = model2->getAnimationState(item->getText().c_str());
		mAnimationState2 -> setEnabled(true);
		mAnimationState2 -> setLoop(true);

		return true;
	}






	
	//example frame listener
	bool frameStarted(const Ogre::FrameEvent &evt)
	{
		if (mAnimationState1) mAnimationState1->addTime( evt.timeSinceLastFrame );
		if (mAnimationState2) mAnimationState2->addTime( evt.timeSinceLastFrame );
		//displayDebug();

		addAnimations(model1, model2, resultModel);
		handleKeyboard(evt.timeSinceLastFrame);
		
		

		return ExampleFrameListener::frameStarted( evt );
	}

	bool frameEnded(const FrameEvent& evt)
	{
	  if (mShutdownRequested)
		  return false;
	  else
		  return ExampleFrameListener::frameEnded(evt);
	}

	//CEGUI creation and update
	void setupGUI()
		{
			//CEGUI settings
			mGUIRenderer = new CEGUI::OgreCEGUIRenderer(mWindow, Ogre::RENDER_QUEUE_OVERLAY, false, 3000, mSceneMgr);
			mGUISystem = new CEGUI::System(mGUIRenderer);
			CEGUI::Logger::getSingleton().setLoggingLevel(CEGUI::Informative);

			CEGUI::SchemeManager::getSingleton().loadScheme((CEGUI::utf8*)"TaharezLookSkin.scheme");
			mGUISystem->setDefaultMouseCursor((CEGUI::utf8*)"TaharezLook", (CEGUI::utf8*)"MouseArrow");
			CEGUI::MouseCursor::getSingleton().setImage("TaharezLook", "MouseMoveCursor");
			mGUISystem->setDefaultFont((CEGUI::utf8*)"BlueHighway-12");
			mEditorGuiSheet= CEGUI::WindowManager::getSingleton().createWindow((CEGUI::utf8*)"DefaultWindow", (CEGUI::utf8*)"Sheet");  
			mGUISystem->setGUISheet(mEditorGuiSheet);

			mEditorGuiSheet = CEGUI::WindowManager::getSingleton().loadWindowLayout((CEGUI::utf8*)"Tutorial Gui.xml");
			mGUISystem->setGUISheet(mEditorGuiSheet);
			//CEGUI::PushButton* quitButton = (CEGUI::PushButton*)CEGUI::WindowManager::getSingleton().getWindow((CEGUI::utf8*)"Quit");



			ResourceGroupManager *rsm = ResourceGroupManager::getSingletonPtr();
			CEGUI::WindowManager& wMgr = CEGUI::WindowManager::getSingleton();

			StringVector groupNamesList = rsm->getResourceGroups();

			{
			std::vector<Ogre::String>::iterator itGroup = groupNamesList.begin();
			for(; itGroup != groupNamesList.end(); ++itGroup) 
			{
				try 
				{
					rsm->initialiseResourceGroup (*itGroup);
				}
				catch(...)
				{
				}
			}

			}
			
			
			//  All Mesh From all corresponding Groups
			CEGUI::Combobox* cMeshBox = (CEGUI::Combobox*) wMgr.getWindow("MeshViewer/MeshBox");
			cMeshBox->resetList ();
			
			std::vector<Ogre::String>::const_iterator itGroup = groupNamesList.begin();
			while (itGroup != groupNamesList.end())
			{
				StringVectorPtr resourceNames = 
					ResourceGroupManager::getSingleton().findResourceNames(*itGroup, 
						"*.mesh" );

				std::vector<Ogre::String>::const_iterator itResourceName = resourceNames->begin();
				while ( itResourceName != resourceNames->end() )
				{
					CEGUI::ListboxTextItem* item = new CEGUI::ListboxTextItem(*itResourceName);

					item->setSelectionBrushImage(LOOKNFEEL, BRUSH);
					item->setSelectionColours(SELECTED_COLOR);
					item->setTextColours (BASIC_COLOR);

					cMeshBox->addItem(item);
					
					++itResourceName;
				} 
				++itGroup;
			}

			//register listiner functions
			CEGUI::WindowManager::getSingletonPtr()->getWindow("MeshViewer/MeshBox")->subscribeEvent(
			CEGUI::Combobox::EventListSelectionAccepted,
			CEGUI::Event::Subscriber(&GuiFrameListener::handleMeshSelect, this));


			CEGUI::WindowManager::getSingletonPtr()->getWindow("MeshViewer/Animation1")->subscribeEvent(
			CEGUI::Combobox::EventListSelectionAccepted,
			CEGUI::Event::Subscriber(&GuiFrameListener::handleModel1Select, this));

			CEGUI::WindowManager::getSingletonPtr()->getWindow("MeshViewer/Animation2")->subscribeEvent(
			CEGUI::Combobox::EventListSelectionAccepted,
			CEGUI::Event::Subscriber(&GuiFrameListener::handleModel2Select, this));

			
		}




	void animationBoxUpdate()
	{
		CEGUI::Combobox* combo1 = (CEGUI::Combobox*) CEGUI::WindowManager::getSingleton().getWindow("MeshViewer/Animation1");
		CEGUI::Combobox* combo2 = (CEGUI::Combobox*) CEGUI::WindowManager::getSingleton().getWindow("MeshViewer/Animation2");
		
		//combo1->resetList();
		//combo2->resetList();
		

		AnimationStateSet* mAnimStateSet = model1->getAllAnimationStates();
		int mNumAnimation = 0;
		if (mAnimStateSet) 
		{
			AnimationStateIterator itr = mAnimStateSet->getAnimationStateIterator();
			while (itr.hasMoreElements ()) 
			{
				AnimationState* aState = itr.getNext ();

				CEGUI::ListboxTextItem* item = new CEGUI::ListboxTextItem(aState->getAnimationName());
				item->setSelectionBrushImage(LOOKNFEEL, BRUSH);
				item->setSelectionColours(SELECTED_COLOR);
				item->setTextColours (BASIC_COLOR);

				combo1->addItem(item);
				combo2->addItem(item);

				mNumAnimation++;
			}
		}
	};

	void jointBoxUpdate()
	{

	CEGUI::Combobox* combo = (CEGUI::Combobox*) CEGUI::WindowManager::getSingleton().getWindow("MeshViewer/Joints");
		

	Skeleton *skel = model1->getSkeleton();
	Skeleton::BoneIterator bi = skel->getBoneIterator();

	int joints = skel->getNumBones();
	string i;

	for (int j = 0; j < joints/2; j++)
	{
		i = bi.peekNext()->getName() + " weights: ............. 1.0 : 0.0";

		CEGUI::ListboxTextItem* item = new CEGUI::ListboxTextItem(i);
		item->setSelectionBrushImage(LOOKNFEEL, BRUSH);
		item->setSelectionColours(SELECTED_COLOR);
		item->setTextColours (BASIC_COLOR);

		combo->addItem(item);

		bi.moveNext();
	};

	for (int j = joints/2; j < joints; j++)
	{
		i = bi.peekNext()->getName() + " weights: ............. 0.0 : 1.0";
		
		CEGUI::ListboxTextItem* item = new CEGUI::ListboxTextItem(i);
		item->setSelectionBrushImage(LOOKNFEEL, BRUSH);
		item->setSelectionColours(SELECTED_COLOR);
		item->setTextColours (BASIC_COLOR);

		combo->addItem(item);

		bi.moveNext();
	};

	}

	
	
	
	//mouse listener
	bool mouseMoved( const OIS::MouseEvent &e ) 
	{
	  using namespace OIS;

	  CEGUI::System::getSingleton().injectMouseMove(
			  e.state.X.rel,e.state.Y.rel);

	  return true;
	}

	bool mousePressed (const OIS::MouseEvent &e, OIS::MouseButtonID id)
	{
	  CEGUI::System::getSingleton().injectMouseButtonDown(
		convertOgreButtonToCegui(id));

	  return true;
	}

	bool mouseReleased( const OIS::MouseEvent &e, OIS::MouseButtonID id )
	{
	  CEGUI::System::getSingleton().injectMouseButtonUp(
		convertOgreButtonToCegui(id));

	  return true;
	}

	//key listener
	bool keyPressed( const OIS::KeyEvent &e )
	{
	  if(e.key == OIS::KC_ESCAPE)
	  {
		  mShutdownRequested = true;
		  return true;
	  }

	  CEGUI::System::getSingleton().injectKeyDown(e.key);
	  CEGUI::System::getSingleton().injectChar(e.text);

	  return true;
	}

	bool keyReleased( const OIS::KeyEvent &e )
	{
	  CEGUI::System::getSingleton().injectKeyUp(e.key);

	  return true;
	}

	
};







//Application
class RoboApplication : public ExampleApplication
{

public:
	RoboApplication()
	{
	}

	~RoboApplication() 
	{
	   
	};

	   void createCamera(void)
	{
	   // create camera, but leave at default position
	   mCamera = mSceneMgr->createCamera("PlayerCam"); 
	   mCamera->setNearClipDistance(5);
	   mCamera->lookAt(Vector3(0,-50,-300));
	  
	   SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode( "CamNode", Vector3( 0, 0, 500 ) );
	   node = node->createChildSceneNode( "PitchNode" );// Create the pitch node
	   node->attachObject( mCamera );
	   
	}


	

	void createScene(void)
	{
		// create the light
		Light *light = mSceneMgr->createLight( "Light" );
		light->setType( Light::LT_POINT );
		light->setPosition( Vector3(250, 150, 250) );
		light->setDiffuseColour( ColourValue::White );
		light->setSpecularColour( ColourValue::White );
		mSceneMgr->setAmbientLight( ColourValue( 0.25, 0.25, 0.25 ) );

	//	setupGUI();
	
	}

   void createFrameListener(void)
   {
       // Create the FrameListener
	   mFrameListener = new GuiFrameListener(mWindow, mCamera, mSceneMgr);
       mRoot->addFrameListener(mFrameListener);

       // Do not show the frame stats overlay
       mFrameListener->showDebugOverlay(false);
   }
};




#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    RoboApplication app;

    try {
        app.go();
    } catch( Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 
        MessageBoxA( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK |   MB_ICONERROR  | MB_TASKMODAL);
#else
        fprintf(stderr, "An exception has occured: %s\n",
                e.getFullDescription().c_str());
#endif
    }

    return 0;
}

in your "StdAfx.h":

Code: Select all



#include "ExampleApplication.h"

#include <deque>
#include <map>
#include <vector>


#include <OgreNoMemoryMacros.h>
#include <CEGUI/CEGUIImageset.h>
#include <CEGUI/CEGUISystem.h>
#include <CEGUI/CEGUILogger.h>
#include <CEGUI/CEGUISchemeManager.h>
#include <CEGUI/CEGUIWindowManager.h>
#include <CEGUI/CEGUIWindow.h>
#include "OgreCEGUIRenderer.h"
#include "OgreCEGUIResourceProvider.h"
//regular mem handler
#include <OgreMemoryMacros.h>

#include <CEGUI/elements/CEGUIPushButton.h>
#include <CEGUI/elements/CEGUIListboxTextItem.h>
#include <CEGUI/elements/CEGUIListbox.h>
#include <CEGUI/elements/CEGUICombobox.h>
place "Tutorial Gui.xml" like below in media\gui:

Code: Select all

<?xml version="1.0" ?>
<GUILayout>
  <Window Type="DefaultWindow" Name="Tutorial Gui">
    
    <Window Type="TaharezLook/Combobox" Name="MeshViewer/MeshBox" >
      <Property Name="ActiveEditSelectionColour" Value="FF607FFF" />
      <Property Name="InactiveEditSelectionColour" Value="FFFFFFFF" />
      <Property Name="MaxEditTextLength" Value="1073741823" />
      <Property Name="NormalEditTextColour" Value="AAAAAAFF" />
      <Property Name="ReadOnly" Value="True" />
      <Property Name="SelectedEditTextColour" Value="FFFFFFFF" />
      <Property Name="Text" Value="Select Mesh" />
      <Property Name="UnifiedAreaRect" Value="{{0.00,0.0},{0.0,0.005},{0.14,0.0},{0.82,0.0}}" />
      <Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
    </Window>
    
     <Window Type="TaharezLook/Combobox" Name="MeshViewer/Animation1" >
      <Property Name="ActiveEditSelectionColour" Value="FF607FFF" />
      <Property Name="InactiveEditSelectionColour" Value="FFFFFFFF" />
      <Property Name="MaxEditTextLength" Value="1073741823" />
      <Property Name="NormalEditTextColour" Value="AAAAAAFF" />
      <Property Name="ReadOnly" Value="True" />
      <Property Name="SelectedEditTextColour" Value="FFFFFFFF" />
      <Property Name="Text" Value="Select 1st Animation" />
      <Property Name="UnifiedAreaRect" Value="{{0.26,0.0},{0.0,0.005},{0.45,0.0},{0.35,0.0}}" />
      <Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
    </Window>
    
    <Window Type="TaharezLook/Combobox" Name="MeshViewer/Animation2" >
      <Property Name="ActiveEditSelectionColour" Value="FF607FFF" />
      <Property Name="InactiveEditSelectionColour" Value="FFFFFFFF" />
      <Property Name="MaxEditTextLength" Value="1073741823" />
      <Property Name="NormalEditTextColour" Value="AAAAAAFF" />
      <Property Name="ReadOnly" Value="True" />
      <Property Name="SelectedEditTextColour" Value="FFFFFFFF" />
      <Property Name="Text" Value="Select 2nd Animation" />
      <Property Name="UnifiedAreaRect" Value="{{0.56,0.0},{0.0,0.005},{0.75,0.0},{0.35,0.0}}" />
      <Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
    </Window>
      
    <Window Type="TaharezLook/Combobox" Name="MeshViewer/Joints" >
      <Property Name="ActiveEditSelectionColour" Value="FF607FFF" />
      <Property Name="InactiveEditSelectionColour" Value="FFFFFFFF" />
      <Property Name="MaxEditTextLength" Value="1073741823" />
      <Property Name="NormalEditTextColour" Value="AAAAAAFF" />
      <Property Name="ReadOnly" Value="True" />
      <Property Name="SelectedEditTextColour" Value="FFFFFFFF" />
      <Property Name="Text" Value="Joint Weights... (Anim1 : Anim2)" />
      <Property Name="UnifiedAreaRect" Value="{{0.15,0.0},{0.4,0.005},{0.45,0.0},{0.95,0.0}}" />
      <Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
    </Window>
    
    <Window Type="TaharezLook/Combobox" Name="MeshViewer/AminTree" >
      <Property Name="ActiveEditSelectionColour" Value="FF607FFF" />
      <Property Name="InactiveEditSelectionColour" Value="FFFFFFFF" />
      <Property Name="MaxEditTextLength" Value="1073741823" />
      <Property Name="NormalEditTextColour" Value="AAAAAAFF" />
      <Property Name="ReadOnly" Value="True" />
      <Property Name="SelectedEditTextColour" Value="FFFFFFFF" />
      <Property Name="Text" Value="Animation tree here..." />
      <Property Name="UnifiedAreaRect" Value="{{0.5,0.0},{0.4,0.005},{0.9,0.0},{0.95,0.0}}" />
      <Property Name="UnifiedMaxSize" Value="{{1.000000,0.000000},{1.000000,0.000000}}" />
    </Window>
    
    
   </Window>
</GUILayout>
in your your resource cfg comment out last lines:

Code: Select all

#Zip=../../media/packs/cubemap.zip
#Zip=../../media/packs/cubemapsJS.zip
#Zip=../../media/packs/dragon.zip
#Zip=../../media/packs/fresneldemo.zip
#Zip=../../media/packs/ogretestmap.zip
#Zip=../../media/packs/skybox.zip
and remove all mesh files that do NOT have a skeleton file matching in media/models(like you have robot.mesh and robot.skeleton)
this is to avoid loading meshes without skeletons if you choose to load such a mesh in a program it will crash. will solve it soon.


Please let me know if you have problems with running it. Most of the time after the exams was spend on learning CEGUI and making it work. Let me know how if you have any info on my lame bugs and if you like the plan of making this a first step of hierarhical animation editor.
User avatar
Wolfmanfx
OGRE Team Member
OGRE Team Member
Posts: 1525
Joined: Fri Feb 03, 2006 10:37 pm
Location: Austria - Leoben
x 99
Contact:

Post by Wolfmanfx »

Maybe is too late :) but i think it would be a better approach if you are using a real GUI Toolkit like wxwidgets, gtk+ cause CeGui lacks in some areas like tree views.
And also there is some code around the forum/wiki how to setup Ogre + WxWidgets so maybe u give it a try i think u will progress much faster with it instead of using CeGui.

Keep on working and good luck :)
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

Wolfmanfx wrote:Maybe is too late :) but i think it would be a better approach if you are using a real GUI Toolkit like wxwidgets, gtk+ cause CeGui lacks in some areas like tree views.
And also there is some code around the forum/wiki how to setup Ogre + WxWidgets so maybe u give it a try i think u will progress much faster with it instead of using CeGui.

Keep on working and good luck :)
yeah not the best timing;). i`d gladly learn this WxWidgets, it would be good for me, but i`m not sure if it would be best for the project to spend another week to make things work together on a basic level before i can actually make progress. perhaps if someone who knows this system proposes working interface like the one above(this should be hours if you are an expert in wx no?), my switch to WxWidgets would be beneficial for the project. Perhaps you can help here, Wolfmanfx?

to all. please feel free to tell me if you are even able to make my code run/have some remarks on it.
User avatar
tuan kuranes
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2653
Joined: Wed Sep 24, 2003 8:07 am
Location: Haute Garonne, France
x 4
Contact:

Post by tuan kuranes »

a) Don't add the same new'ed item to 2 different list. When resetting list, each tries to delete the same item. You have to add a new item to each list.

b) Check ogre gui sample that comes with ogresdk or inside ogre cvs sample directory. listbox + addable value + sliders is the solution. ceguimeshviewer also use same scheme to set animation speed

c) in setupGUI(). Add fast filtering of mesh without skeleton animation using

Code: Select all

MeshPtr myMesh = MeshManager::getSingleton().load(*itResourceName, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME);
					  toAdd = myMesh->hasSkeleton();
or

Code: Select all

const String meshName(*itResourceName);
const String skelName(meshName.substr(0, meshName.length() - 5));
				  itResourceSkelName = std::find (resourceSkelNames->begin(), resourceSkelNames->end(), skelName + ".skeleton");
				  if ( itResourceSkelName != resourceSkelNames->end() )
d) ... todo ...

e) don't delete mGUISystem

f) Distribute Zip files of source code. Use a batch script file that produce that zip (7zip does command line.). You should be able to make a one click release or/and backup. (the 2. in part of obligatory step of any sofwtare project) (I can host files if you need.)
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

all i can say is wow.

that's called help
User avatar
Wolfmanfx
OGRE Team Member
OGRE Team Member
Posts: 1525
Joined: Fri Feb 03, 2006 10:37 pm
Location: Austria - Leoben
x 99
Contact:

Post by Wolfmanfx »

Hi,
So my self is using gtk+ :) cause i also made http://sourceforge.net/projects/gtkwindowforms its more confortable as wxAUI ;) but i think gtk+ would to heavy to learn for you.
In the CVS Head the GSOC project for the Material editor is using wxWidgets and he also commited so look at it.

Look at the wiki http://www.ogre3d.org/wiki/index.php/Sp ... gets&go=Go
and dont forget sinbad is also using wxWidgets so there are a lot of people the can help you with that toolkit.

The reason why iam think it would be worth to try it is that you will progress faster last year i wrote an editor in CeGUI and it really sucked :) but maybe CeGUI is much better than 0.4
http://www.ogre3d.org/phpBB2/viewtopic. ... ight=arpes
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

i`d like to share this installer and ask for help with bugs and problems if you are willing:

http://www.savefile.com/files/879533

any advices/code propositions are very welcome.
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

Remarks

1. current state and plans development
------------------
We have:
- nicer interface(some help needed, see point 3)
- joint grouping for blending operations for fast and precise control
- continous weights for all joint groups supported(linear quaternion interpolation used)
Soon:
- working add/delete joint groups buttons(very easy, first on my list now)
- finish group selection for joints(almost done i have small problem here)
- rename joint groups button + text field, scroll bar for group weights distribiution (between animation 1 and 2)
- save/load for each mesh joint groups, weights etc.
- render source animation into small window in the interface instead as it is like now
- animation tree: hierarhical structure like described in the project web page
- "event" descriptions(explian more later, event can be a shoot, walk tempo change etc,
that will make weights in certain groups change over time), so you can use keyboard for dynamic controll
like: press s to shoot(while walking, standing or whatever), press 1..9 to go between run and walk etc
- more meshes with at least: walk, run, aim, shoot, lookat etc animations. Animations with staggering/drunk or similiar walk/stand would be nice!

2. control:
------------------
Click on tab buttons to see the contents.
First select mesh(not the fish(robot recomended)!! see bugs.), than select source animations
(i recomend robot, walk + shoot/idle or ninja attack1 + attrack2, as they work with the
predefined joint grouping). See the joint grouping(so far first half = lower body, second upper,
true only for robot), weights etc.


left, right = rotation
up, down = move models far and near
to change the mesh + animations click buttons...


3. bugs and possible required help(also see We want section in point 1.)
------------------
a) some meshes may not work egz. = fish.mesh (perhaps the model radius is the problem, will look into that)
b) camera fit sometimes reguires to press up/down to find a nice view for all 3 models
c) if the source models are outside the screen, they are no longer animated and the result is also static
remark: b) + c) may be solved if i know how to render source animations on the interface
d) opengl does not work, do you have the same problem, if yes, any ideas why??
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

i have some issues with the CEGUI, perhaps someone will help:
i want to be able to select element on a list(joint or joint group) and than by using a diffrent element(a button or a scrollbar) modify the selected element. i try to do it like that(registered scrollbar handler):

Code: Select all

bool weightChange(const CEGUI::EventArgs& e)
	{
		if (groupList->getItemCount() == 0) return false;
		if (groupList->getSelectedCount())
		{
			editedGroup = weights[groupList->getFirstSelectedItem()->getID()] = weightBar->getScrollPosition() / 240.0;;			
		};

		
		fillGroupList(); //show results

		return true;
	}
groupList is a pointer to a listbox with selected elements;
but:
1. i thought getId() returns a position(index) on a list, but apparently it does not. how can i get the index of selected element in groupList.
2. the selection is gone after that. i can no longer adress this element.
ofcourse i can remember the last edited element like:

Code: Select all

if (groupList->getSelectedCount() > 0)
		{
			editedGroup = groupList->getFirstSelectedItem()->getID();
			
		};
and than operate on editedGroup. but perhaps there is a nicer solution that allows me to have selection active on the list even if i use other gui elements?
User avatar
Kencho
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4011
Joined: Fri Sep 19, 2003 6:28 pm
Location: Burgos, Spain
x 2
Contact:

Post by Kencho »

You should really consider working full-time on the animation and IK support, and leave aside the interface part, and not to mention working on new meshes!

Don't miss what was the original proposal and what you compromised to do.
Image
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

ok, but i have to have some kind of gui, it is true it takes me most time now since i use this system for the first time.

i will follow your advice, leave interface as much as possible as it is(i will add the load option so people can bypass the lack of gui functionalities by text files) and focus on the animation tree.
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

and i was NOT going to create meshes! i was asking for them from the community.
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

this is a new version of a blender. With changes since the last exchange of opinions with my mentor. this time you can edit all the main elements like define joint groups, weights etc. Should be able to give some nice effects if one defines groups and weights in a good way. I will NOT finish the interface soon so if anyone would like to play with a code please do. If you know the CEGUI should be easy. thanks for any help/comments

http://www.savefile.com/files/880044


SOME REMARKS(see readme.txt for more):
1. current state and plans development
------------------
We have:
- nicer interface(some help needed, see point 3, NOT going to look into that for now, use txt files for loading data)
- joint grouping for blending operations for fast and precise controll
- continous weights for all joint groups supported(linear quaternion interpolation used)
- load external mesh setup(joint groups, weights, soon tree)
Next step:
- animation tree: hierarhical structure like described in the project web page.
- "event" descriptions(explian more later, event can be a shoot, walk tempo change etc,
that will make weights in certain groups change over time), so you can use keyboard for dynamic controll
like: press s to shoot(while walking, standing or whatever), press 1..9 to go between run and walk etc
- more meshes with at least: walk, run, aim, shoot, lookat etc animations. Animations with staggering/drunk or similiar walk/stand would be nice!
- (?)render source animation into small window in the interface instead as it is like now

2.GRAPHICAL INTERFACE:
As i do not want to focus on the interface at this phase anymore, you shoud use txt files
to define joint groups and the weights of animations in a group.

Example:
I.You select robot mesh.
II.You can see the joint tree in the animation tab. You can also see that each joint is assigned to
one of the upper or lower body joint group. You can also see how much weight is assigned to each
animation for a given group.
III. Now alt+tab and open robot.txt(will put them in some more resonable form later) you can see:
1 number of groups
2 list of names of groups together with the weight of 1st animation(2nd animation is 1- 1st)
3. number of joints
4. list of joint names with assigned joing group index
Edit the file to change what you wish. Save.
IV. Alt+tab again to app. press "load setup" button.

The default setup is the most primitive that can be of any use, and only for the robot.
If you are able to make some inteligent joint groups to blend animations together in a
meaningfyll way in any meshes, please send me the txt files. For ex.: in robot it self one could
make third joint group for hands and for walk + shoot have:
LowerBody: walk = 1.0 shoot = 0.0
UpperBody(torso): walk = 0.8 shoot = 0.2
Hands: walk = 0.0 shoot = 1.0
This should make robot swing the upper body while walking and plus have a nice shooting animation.
Other meshes like ninja etc should be much more fun. I have no time to do it now.
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

Focusing on a animation tree now. First version should be ready tomorow.
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

ok i have animation tree in it`s first version.

http://www.savefile.com/files/880457

it is a binary tree structure, you can modify and load it from a txt file like it was a case with the joint groups. on every level you can assign weights of every joint group to an animation.
for now the tree is only kept in "tree.txt" for ilustration, later all meshes will have many animation trees. "tree.txt" looks like that:

Code: Select all

Move+Shoot 1 1
 Walk+run 0.5 1
   Walk -0.5 -0.5
	 Run -0.5 -0.5
 Shoot -1 -0.0
the string is animation name, numbers after the string are weights for joint groups, their number should be the same as the used group number.
spacing is just for clearity, program does not use it. if there is a minus before any weight it means that the animation is a leaf in the tree(that it is actual existing artist created animation). the minus is ignored in the system. if no weight is negative it means the animation is a parent. this is all temporary other representation will be used later.

The program reads the file, and can be asked to return a list of all leaves with summary weight for each group witch is a result of multiplication of partial weights of every level of tree hierarchy. (hope it is clear, will discuss it later, but for example: walk would have: 1.0 * 0.5 * 0.5 = 0.25 for both joint groups in the example before)

this is a first realization of the project`s main assumption - hierarchical control blending. so far it is not connected to the interface(only visualization of the tree + weights of each group for each animation) or animation process but you can take a look at the code, the tree is there and is doing what it should. My next step will be to replace visualization of blending of 2 simple animations by visualization of blending at any level of the tree(user clicks on an animation on any tree level and he is given it`s visualization and the visualization of it`s siblings).

if there would be any kind cegui guru with understanding of my intentions willing to patch this poor interface this would be most useful. all other code modifications/advices/comments are really welcome. thx.
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

i have a specific question: how can i use animated skeletons without putting entity representing them on the screen? i do not want every animation in ther hierarchy on the screen... but i need all their results for blending. any help?
User avatar
tuan kuranes
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2653
Joined: Wed Sep 24, 2003 8:07 am
Location: Haute Garonne, France
x 4
Contact:

Post by tuan kuranes »

User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

yes i know that, but i actually ask how to select animation for that skelton and make it play without having the entity on the screen and to be able to refer to the bone orientations and postions in every frame like in:

Code: Select all

		Skeleton::BoneIterator bi1 = model1->getSkeleton()->getBoneIterator();
		Skeleton::BoneIterator bi2 = model2->getSkeleton()->getBoneIterator();
		Skeleton::BoneIterator bi3 = resultModel->getSkeleton()->getBoneIterator();
		for (int j = 0; j < jointNr; j++)
		{
			bi3.peekNext()->setManuallyControlled(true);
			float t = 1 - weights[ jointToGroup[ bi1.peekNext()->getName()] ];

			Quaternion q1 = bi1.peekNext()->getOrientation();
			Quaternion q2 = bi2.peekNext()->getOrientation();
			Quaternion q3;

			q3.x = q1.x + t*(q2.x - q1.x);

etc..
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66
Contact:

Post by sinbad »

You can use Skeleton::setAnimationState to apply a set of animations. You would also usually need to create a SkeletonInstance first so that you're modifying that and not the base skeleton, this is what Entity does.
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

ok sindbad will try like that.

in the mean time i have a problem. i started dividing the code since it was in one file so far but it was growing big and i wanted to do some structurisation. after moving definitions of methods to cpp, i get linker errors like:

Code: Select all

main.obj : error LNK2005: "enum CEGUI::MouseButton __cdecl convertOgreButtonToCegui(int)" (?convertOgreButtonToCegui@@YA?AW4MouseButton@CEGUI@@H@Z) already defined in AnimationBlenderApp.obj
main.obj : error LNK2005: "enum CEGUI::MouseButton __cdecl convertOgreButtonToCegui(int)" (?convertOgreButtonToCegui@@$$FYA?AW4MouseButton@CEGUI@@H@Z) already defined in AnimationBlenderApp.obj
main.obj : error LNK2005: "class Ogre::SceneManager * mSceneMgr" (?mSceneMgr@@3PAVSceneManager@Ogre@@A) already defined in AnimationBlenderApp.obj
main.obj : error LNK2005: "void __cdecl addAnimations(class Ogre::Skeleton *,class Ogre::Skeleton *,class Ogre::Skeleton *,class std::vector<float,class std::allocator<float> > &)" (?addAnimations@@YAXPAVSkeleton@Ogre@@00AAV?$vector@MV?$allocator@M@std@@@std@@@Z) already defined in AnimationBlenderApp.obj
main.obj : error LNK2005: "void __cdecl addAnimations(class Ogre::Skeleton *,class Ogre::Skeleton *,class Ogre::Skeleton *,class std::vector<float,class std::allocator<float> > &)" (?addAnimations@@$$FYAXPAVSkeleton@Ogre@@00AAV?$vector@MV?$allocator@M@std@@@std@@@Z) already defined in AnimationBlenderApp.obj
main.obj : error LNK2005: "bool __cdecl treeInsertItem(class CEGUI::Listbox *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,unsigned int,bool)" (?treeInsertItem@@YA_NPAVListbox@CEGUI@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@I_N@Z) already defined in AnimationBlenderApp.obj
main.obj : error LNK2005: "bool __cdecl treeInsertItem(class CEGUI::Listbox *,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,unsigned int,bool)" (?treeInsertItem@@$$FYA_NPAVListbox@CEGUI@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@I_N@Z) already defined in AnimationBlenderApp.obj
main.obj : error LNK2005: "class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > mTreeViewFolded" (?mTreeViewFolded@@3V?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@A) already defined in AnimationBlenderApp.obj
main.obj : error LNK2005: "class std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,int,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,int> > > jointToGroup" (?jointToGroup@@3V?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@HU?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@std@@@2@@std@@A) already defined in AnimationBlenderApp.obj
AnimationBlenderApp.obj : error LNK2001: unresolved external symbol "public: static int AnimationTree::modelCount" (?modelCount@AnimationTree@@2HA)
C:\Program Files\OgreSDK\bin\Release\AnimationBlender.exe : fatal error LNK1120: 1 unresolved externals
Build log was saved at "file://c:\Program Files\OgreSDK\projects\AnimBlendCegui\obj\Release\BuildLog.htm"
AnimationBlender - 11 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

the cpp has just:

Code: Select all

#include "StdAfx.h"
#include "AnimationBlenderApp.h"
and later definitions...

i know it is something about the settings, suspect crt library problem or sth but did n`t solve that so far. can you help guys?
User avatar
sinbad
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 19269
Joined: Sun Oct 06, 2002 11:19 pm
Location: Guernsey, Channel Islands
x 66
Contact:

Post by sinbad »

Make sure you do a clean build when you move things around.
User avatar
jarek108
Halfling
Posts: 72
Joined: Mon Mar 05, 2007 1:11 am

Post by jarek108 »

cleaned, rebuild the still the same
Locked