Ejemplo n.º 1
0
void SceneAnimator::load(PlatformContext& context, ByteBuffer& dataIn) {
    // make sure to clear this before writing new data
    release();

    _skeleton = loadSkeleton(dataIn, nullptr);

    stringImpl boneName;
    uint32_t nsize = 0;
    dataIn >> nsize;
    _bones.resize(nsize);
    for (uint32_t i(0); i < nsize; i++) {
        dataIn >> boneName;
        _bones[i] = _skeleton->find(boneName);
    }
    _skeletonDepthCache = nsize;
    // the number of animations
    dataIn >> nsize;
    _animations.resize(nsize);
    
    uint32_t idx = 0;
    for (std::shared_ptr<AnimEvaluator>& anim : _animations) {
        anim = std::make_unique<AnimEvaluator>();
        AnimEvaluator::load(*anim, dataIn);
        // get all the animation names so I can reference them by name and get the correct id
        hashAlg::insert(_animationNameToID, _ID(anim->name().c_str()), idx++);
    }
    
    init(context);
}
Ejemplo n.º 2
0
Bone* SceneAnimator::loadSkeleton(ByteBuffer& dataIn, Bone* parent) {
    stringImpl tempString;
    // create a node
    Bone* internalNode = MemoryManager_NEW Bone();
    // set the parent, in the case this is the root node, it will be null
    internalNode->_parent = parent;  
    // the name of the bone
    dataIn >> tempString;
    internalNode->name(tempString);
    // the bone offsets
    dataIn >> internalNode->_offsetMatrix;
    // original bind pose
    dataIn >> internalNode->_originalLocalTransform;
 
    // a copy saved
    internalNode->_localTransform = internalNode->_originalLocalTransform;
    calculateBoneToWorldTransform(internalNode);
    // the number of children
    U32 nsize = 0;
    dataIn >> nsize;

    // recursively call this function on all children
    // continue for all child nodes and assign the created internal nodes as our children
    for (U32 a = 0; a < nsize; a++) {
        internalNode->_children.push_back(loadSkeleton(dataIn, internalNode));
    }
    return internalNode;
}
Ejemplo n.º 3
0
//-----------------------------------------------------------------------------
//! Loads the skeleton
void SLAssimpImporter::loadSkeleton(SLJoint* parent, aiNode* node)
{
    if (!node)
        return;


    SLJoint* joint;
    SLstring name = node->mName.C_Str();
    if (!parent)
    {
	    logMessage(LV_normal, "Loading skeleton skeleton.\n");
        _skeleton = new SLSkeleton;
        _jointIndex = 0;

        joint = _skeleton->createJoint(name, _jointIndex++);
        _skeleton->root(joint);
    }
    else
    {
        joint = parent->createChild(name, _jointIndex++);
    }

    joint->offsetMat(getOffsetMat(name));
    
    // set the initial state for the joints (in case we render the model without playing its animation)
    // an other possibility is to set the joints to the inverse offset matrix so that the model remains in
    // its bind pose
    // some files will report the node transformation as the animation state transformation that the
    // model had when exporting (in case of our astroboy its in the middle of the animation=
    // it might be more desirable to have ZERO joint transformations in the initial pose
    // to be able to see the model without any joint modifications applied
    // exported state
    
    // set the current node transform as the initial state
    /**
    SLMat4f om;
    memcpy(&om, &node->mTransformation, sizeof(SLMat4f));
    om.transpose();
    joint->om(om);
    joint->setInitialState();
    /*/
    // set the binding pose as initial state
    SLMat4f om;
    om = joint->offsetMat().inverse();
    if (parent)
        om = parent->updateAndGetWM().inverse() * om;
    joint->om(om);
    joint->setInitialState();
    /**/


    for (SLuint i = 0; i < node->mNumChildren; i++)
        loadSkeleton(joint, node->mChildren[i]);
}
Ejemplo n.º 4
0
Skeleton *AnimationLibrary::getSkeleton(const std::string &id)
{
	std::map<std::string, Skeleton *>::iterator it = m_animations.find(id);
	if (it == m_animations.end()) {
		std::pair<std::map<std::string, Skeleton *>::iterator, bool> ret;
		ret = m_animations.insert(
			std::pair<std::string, Skeleton *>(id, loadSkeleton(id)));
		it = ret.first;
	}
	return it->second;
}
Ejemplo n.º 5
0
// Create a model by deserializing it from Json
Model::Model(const Json::Value& root, const std::string& directory, TextureCache &_textureCache)
    : meshes(0, NULL), skeleton(new Node()), textureCache(_textureCache), previousProgram(NULL), uploaded(false)
{
    // Load animations
    loadAnimations(root);
    
    // Load materials
    loadMaterials(root, directory);
    
    // Load mesh data
    loadMeshes(root);
    
    // Load node data
    loadSkeleton(root);
    
    // Load parts
    loadParts(root);
}
Ejemplo n.º 6
0
Archivo: Player.cpp Proyecto: faod/ld30
Player::Player(Game& g, b2Vec2 p) : Character(g),swordFix(NULL), left(false), right(false), landed(true), contact(false), lastproc(0), life(100), attacking(false), attackcooldown(0)
{
	bodyDef.type = b2_dynamicBody;
	bodyDef.position.Set(p.x, p.y);
	bodyDef.fixedRotation = true;

	body = g.w.CreateBody(&bodyDef);

	dynamicBox.SetAsBox(.25f, 0.9f);
	
	fixtureDef.shape = &dynamicBox;
	fixtureDef.density = 5.0f;
	fixtureDef.friction = 0.0f;
	
	fixtureDef.filter.categoryBits = PLAYER;
	fixtureDef.filter.maskBits = MONSTER | TRIGGER | WALL | SWORD;

	(body->CreateFixture(&fixtureDef))->SetUserData(this);

	//add "feet" to detect floor
	dynamicBox.SetAsBox(0.2, 0.05, b2Vec2(0, 0.9f), 0);
	fixtureDef.isSensor = true;
	fixtureDef.density = 0.1;
	fixtureDef.filter.categoryBits = FOOT;
	fixtureDef.filter.maskBits = WALL | MONSTER;
	(body->CreateFixture(&fixtureDef))->SetUserData(this);

	//add sword to kill monsters
	dynamicBox.SetAsBox(0.4, 0.1, b2Vec2(0.65, 0), 0);
	swordDef.shape = &dynamicBox;
	swordDef.isSensor = true;
	swordDef.density = 0.1;
	swordDef.filter.categoryBits = SWORD;
	swordDef.filter.maskBits = MONSTER;

	// Loads the Spine model
	ALLEGRO_PATH *path, *resourceDir, *file;
	resourceDir= al_get_standard_path(ALLEGRO_RESOURCES_PATH);
	std::cerr << al_path_cstr(resourceDir, ALLEGRO_NATIVE_PATH_SEP) << std::endl;

	if (modelAtlas == NULL) {
		file = al_create_path("data/animations/hero.atlas");
		path =  al_clone_path(resourceDir);
		al_join_paths(path, file); al_destroy_path(file);
		modelAtlas = spAtlas_createFromFile(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP), NULL);
		if (!modelAtlas) throw Failure("Failed to load the hero's atlas.");
		al_destroy_path(path);
		jsonSkel = spSkeletonJson_create(modelAtlas);

		file = al_create_path("data/animations/hero.json");
		path =  al_clone_path(resourceDir);
		al_join_paths(path, file); al_destroy_path(file);
		modelData = spSkeletonJson_readSkeletonDataFile(jsonSkel, al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP));
		if (!modelData) throw Failure("Failed to load the hero's data.");
		al_destroy_path(path); al_destroy_path(resourceDir);

		stateData = spAnimationStateData_create(modelData);
		spAnimationStateData_setMixByName(stateData, "walk", "rest", 0.2f);
		spAnimationStateData_setMixByName(stateData, "rest", "walk", 0.2f);
		spAnimationStateData_setMixByName(stateData, "rest", "slash", 0.1f);
		spAnimationStateData_setMixByName(stateData, "slash", "rest", 0.1f);
		spAnimationStateData_setMixByName(stateData, "walk", "slash", 0.1f);
		spAnimationStateData_setMixByName(stateData, "slash", "walk", 0.1f);
	
		model = loadSkeleton(modelData, stateData);
		if (!model) throw Failure("Failed to load the hero's skeleton.");

		spAnimationState_setAnimationByName(model->state, 0, "rest",  true);
	}
}
Ejemplo n.º 7
0
Skeleton::Skeleton(const Common::String &filename, Common::SeekableReadStream *data) {
	loadSkeleton(data);
}
Ejemplo n.º 8
0
void updateEditor(SDL_Event event, EditorData* data)
{
	
	GUI_sendEventToGUI(data->gui, &event);

	const unsigned char* keyboardState = SDL_GetKeyboardState(NULL);
	int2 mousePixel;
	SDL_GetMouseState(&mousePixel.x, &mousePixel.y);

	float2 mousePos = pixelToPoint(&data->view, mousePixel);


	updateBones(data);

	switch (event.type)
	{
	case SDL_KEYDOWN:
	{

		switch (event.key.keysym.scancode)
		{
		case SDL_SCANCODE_S:
			if (event.key.keysym.mod == KMOD_LCTRL)
			{
				SDL_Event lastEvent = data->lowEventStack.Top();

				if (lastEvent.key.keysym.scancode == SDL_SCANCODE_S && lastEvent.key.keysym.mod == KMOD_LCTRL)
				{
					// save skeleton

					GUI_WidgetID widget = GUI_addContainer(data->gui, GUI_MAIN_WIDGET, { 400 - 100, 300 - 25, 200, 50}, GUI_Container::Orientation::HORIZONTAL);

					auto callbackSave = [](GUI* gui, GUI_WidgetID widgetID, void* editorData)
					{
						EditorData* data = (EditorData*)editorData;

						GUI_WidgetID widget = GUI_getParentWidget(gui, widgetID);

						const char* filename = GUI_getTextfield(gui, GUI_getChildWidget(gui, widget, 0)).text;

						saveSkeleton(filename, &data->skeleton[0], &data->names[0], data->skeleton.size());

						GUI_removeWidget(gui, widget);
					};

					auto callbackCancel = [](GUI* gui, GUI_WidgetID widgetID, void*)
					{
						GUI_WidgetID widget = GUI_getParentWidget(gui, widgetID);
						GUI_removeWidget(gui, widget);
					};

					GUI_addTextfield(data->gui, widget, { 0, 0, -1, -1 }, "filename");
					GUI_addButton(data->gui, widget, { 0, 0, 50, -1 }, "Save", data, callbackSave);
					GUI_addButton(data->gui, widget, { 0, 0, 50, -1 }, "Cancel", 0, callbackCancel);

					break;
				}
				else if (lastEvent.key.keysym.scancode == SDL_SCANCODE_O && lastEvent.key.keysym.mod == KMOD_LCTRL)
				{
					// load skeleton

					GUI_WidgetID widget = GUI_addContainer(data->gui, GUI_MAIN_WIDGET, { 400 - 100, 300 - 15, 200, 30 }, GUI_Container::Orientation::HORIZONTAL);


					auto callbackLoad = [](GUI* gui, GUI_WidgetID widgetID, void* editorData)
					{
						EditorData* data = (EditorData*)editorData;

						GUI_WidgetID widget = GUI_getParentWidget(gui, widgetID);

						const char* filename = GUI_getTextfield(gui, GUI_getChildWidget(gui, widget, 0)).text;

						strcpy(data->skeletonName, filename);
						
						const SkeletonSave* save = loadSkeleton(filename);

						if (save != 0)
						{
							data->bones.clear();
							data->skeleton.clear();
							data->constraints.clear();
							data->names.clear();

							const char* name = save->names;
							for (int i = 0; i < save->numBones; ++i)
							{
								Bone newBone;
								newBone.jointAngle = { 1, 0 };
								newBone.jointPos = save->jointPos[i];
								newBone.parentJoint = save->parentJoints[i];
								newBone.name = data->names.push({ { 0 } });

								memcpy(data->names[newBone.name].string, name, save->nameLen[i] * sizeof(char));
								name += save->nameLen[i];

								Constraint constraint;
								constraint.minAngle = -PI;
								constraint.maxAngle = 3 * PI;

								data->skeleton.push(newBone);
								data->constraints.push(constraint);
							}

							updateBones(data);
						}

						GUI_removeWidget(gui, widget);
					};

					auto callbackCancel = [](GUI* gui, GUI_WidgetID widgetID, void*)
					{
						GUI_WidgetID widget = GUI_getParentWidget(gui, widgetID);
						GUI_removeWidget(gui, widget);
					};

					GUI_addTextfield(data->gui, widget, { 0, 0, -1, -1 }, "filename");
					GUI_addButton(data->gui, widget, { 0, 0, 50, -1 }, "Load", data, callbackLoad);
					GUI_addButton(data->gui, widget, { 0, 0, 50, -1 }, "Cancel", 0, callbackCancel);



					break;
				}


				data->lowEventStack.Push(event);
			}


			break;
			case SDL_SCANCODE_K:
				if (event.key.keysym.mod == KMOD_LCTRL)
				{
					SDL_Event lastEvent = data->lowEventStack.Top();

					if (lastEvent.key.keysym.scancode == SDL_SCANCODE_S && lastEvent.key.keysym.mod == KMOD_LCTRL)
					{
						// save keyFrame

						GUI_WidgetID widget = GUI_addContainer(data->gui, GUI_MAIN_WIDGET, { 400 - 100, 300 - 15, 200, 30 }, GUI_Container::Orientation::HORIZONTAL);

						auto callbackSave = [](GUI* gui, GUI_WidgetID widgetID, void* editorData)
						{
							EditorData* data = (EditorData*)editorData;

							GUI_WidgetID widget = GUI_getParentWidget(gui, widgetID);

							const char* filename = GUI_getTextfield(gui, GUI_getChildWidget(gui, widget, 0)).text;

							saveKeyFrame(filename, &data->skeleton[0], &data->names[0], data->skeleton.size());

							GUI_removeWidget(gui, widget);
						};

						auto callbackCancel = [](GUI* gui, GUI_WidgetID widgetID, void*)
						{
							GUI_WidgetID widget = GUI_getParentWidget(gui, widgetID);
							GUI_removeWidget(gui, widget);
						};

						GUI_addTextfield(data->gui, widget, { 0, 0, -1, -1 }, "filename");
						GUI_addButton(data->gui, widget, { 0, 0, 50, -1 }, "Save", data, callbackSave);
						GUI_addButton(data->gui, widget, { 0, 0, 50, -1 }, "Cancel", 0, callbackCancel);

						break;
					}
					else if (lastEvent.key.keysym.scancode == SDL_SCANCODE_O && lastEvent.key.keysym.mod == KMOD_LCTRL)
					{
						// load keyframe

						GUI_WidgetID widget = GUI_addContainer(data->gui, GUI_MAIN_WIDGET, { 400 - 100, 300 - 15, 200, 30 }, GUI_Container::Orientation::HORIZONTAL);


						auto callbackLoad = [](GUI* gui, GUI_WidgetID widgetID, void* editorData)
						{
							EditorData* data = (EditorData*)editorData;

							GUI_WidgetID widget = GUI_getParentWidget(gui, widgetID);

							const char* filename = GUI_getTextfield(gui, GUI_getChildWidget(gui, widget, 0)).text;

							strcpy(data->frameName, filename);

							const KeyFrameSave* save = loadKeyFrame(filename);

							if (save != 0)
							{

								const char* name = save->names;
								for (int i = 0; i < save->numBones; ++i)
								{
									int nameID = -1;
									for (int j = 0; j < data->names.size(); ++j)
									{
										if (strncmp(name, data->names[j].string, save->nameLen[i]) == 0)
										{
											nameID = j;
											break;
										}
									}

									if (nameID != -1)
									{

										if (data->skeleton[nameID].name == nameID)
										{
											data->skeleton[nameID].jointAngle = save->jointAngles[i];
										}
										else
										{
											for (int j = 0; j < data->skeleton.size(); j++)
											{
												if (data->skeleton[j].name = nameID)
													data->skeleton[j].jointAngle = save->jointAngles[i];
											}
										}
									}

									name += save->nameLen[i];
								}

								updateBones(data);
							}

							GUI_removeWidget(gui, widget);
						};

						auto callbackCancel = [](GUI* gui, GUI_WidgetID widgetID, void*)
						{
							GUI_WidgetID widget = GUI_getParentWidget(gui, widgetID);
							GUI_removeWidget(gui, widget);
						};

						GUI_addTextfield(data->gui, widget, { 0, 0, -1, -1 }, "filename");
						GUI_addButton(data->gui, widget, { 0, 0, 50, -1 }, "Load", data, callbackLoad);
						GUI_addButton(data->gui, widget, { 0, 0, 50, -1 }, "Cancel", 0, callbackCancel);


						break;
					}


					data->lowEventStack.Push(event);
				}


				break;
		default:
			data->lowEventStack.Push(event);
			break;

		}
		break;
	}
	case SDL_MOUSEBUTTONDOWN:
	{
		data->newBone = -1;

		if (keyboardState[SDL_SCANCODE_A])
		{
			for (int i = 0; i < data->bones.size(); ++i)
			{
				if (pointInRect(mousePos, data->bones[i].rect))
				{
					int name = data->names.push({ "test" });

					Bone newBone;
					newBone.jointAngle = { 1, 0 };
					newBone.jointPos = { 0, 0 };
					newBone.parentJoint = i;
					newBone.name = name;

					Constraint constraint;
					constraint.minAngle = -PI;
					constraint.maxAngle = 3 * PI;

					int newBoneID = data->skeleton.push(newBone);
					data->constraints.push(constraint);

					int* ids = new int[data->skeleton.size()];

					sortSkeleton(&data->skeleton[0], data->skeleton.size(), ids);

					Constraint* tempConstraints = new Constraint[data->constraints.size()];
					memcpy(tempConstraints, &data->constraints[0], sizeof(Constraint) * data->constraints.size());

					for (int i = 0; i < data->constraints.size(); ++i)
					{
						data->constraints[i] = tempConstraints[ids[i]];
					}

					delete[] tempConstraints;

					//find bone again
					data->newBone = ids[newBoneID];

					// rebuild bone selection

					updateBones(data);

					delete[]ids;


					break;
				}



			}
		}
		else if (keyboardState[SDL_SCANCODE_N])
		{

			for (int i = 0; i < data->bones.size(); ++i)
			{
				if (pointInRect(mousePos, data->bones[i].rect))
				{
					
					int2 pos = pointToPixel(&data->view, float2{ data->bones[i].rect.x + 10, data->bones[i].rect.y });
					
					GUI_WidgetID widget = GUI_addContainer(data->gui, GUI_MAIN_WIDGET, intRect{ pos.x, pos.y, 100, 30 }, GUI_Container::HORIZONTAL);

					struct Args
					{
						EditorData* data;
						int boneId;
					}*args = new Args{ data, i };
						

					auto callbackOk = [](GUI* gui, GUI_WidgetID widgetID, void* args)
					{
						EditorData* data = ((Args*)args)->data;
						int boneID = ((Args*)args)->boneId;

						GUI_WidgetID parentID = GUI_getParentWidget(gui, widgetID);

						const char* newName = GUI_getTextfield(gui, GUI_getChildWidget(gui, parentID, 0)).text;

						strcpy(data->names[data->skeleton[boneID].name].string, newName);

						GUI_removeWidget(gui, parentID);

						delete args;
					};

					GUI_addTextfield(data->gui, widget, intRect{ 0, 0, -1, -1 }, data->names[data->skeleton[i].name].string);
					GUI_addButton(data->gui, widget, intRect{ 0, 0, 30, -1 }, "OK", args, callbackOk);

					break;
				}
			}
		}
		else
		{



			for (int i = 0; i < data->bones.size(); i++)
			{
				if (pointInRect(mousePos, data->bones[i].rect))
				{
					data->selectedBones.push(i);
					data->grabbedBone = i;
				}
			}

			if (data->grabbedBone == -1 && !keyboardState[SDL_SCANCODE_LCTRL])
				data->selectedBones.clear();
		}

		break;
	}
	case SDL_MOUSEBUTTONUP:
	{

		data->grabbedBone = -1;
		break;
	}
	case SDL_MOUSEMOTION:
	{

		

		if (SDL_GetMouseState(0, 0) == SDL_BUTTON_MIDDLE)
		{
			data->view.position.x -= (event.motion.xrel / data->view.scale.x);
			data->view.position.y -= (event.motion.yrel / data->view.scale.y);

		}
		else
		{

			float2 motion = rotate({ (float)event.motion.xrel, (float)event.motion.yrel }, data->view.angle) * float2{ 1 / data->view.scale.x, 1 / data->view.scale.y };

			if (data->newBone != -1)
			{
				float2 angle = getBoneWorldTransform(&data->skeleton[0], data->skeleton.size(), data->newBone).angle;

				float2 rel = rotate(float2{ motion.x, motion.y }, negateRotation(angle));

				data->skeleton[data->newBone].jointPos += rel;
			}


			if (data->grabbedBone != -1)
			{
				if (keyboardState[SDL_SCANCODE_LCTRL])
				{
					float2 angle = getBoneWorldTransform(&data->skeleton[0], data->skeleton.size(), data->skeleton[data->grabbedBone].parentJoint).angle;

					float2 rel = rotate(float2{ motion.x, motion.y }, negateRotation(angle));

					data->skeleton[data->grabbedBone].jointPos += rel;
				}
				else
				{
					animateCCDIKSelection(&data->skeleton[0], &data->constraints[0], data->skeleton.size(),
						&data->selectedBones[0], data->selectedBones.size(), data->grabbedBone, mousePos - float2{ 400, 300 });
				}
			}

		}

		break;
	}
	case SDL_MOUSEWHEEL:
	{
		data->view.scale.x += event.wheel.y*0.1f;
		data->view.scale.y += event.wheel.y*0.1f;

		break;
	}
	}


	
}
Ejemplo n.º 9
0
/*! Loads the scene from a file and creates materials with textures, the 
meshes and the nodes for the scene graph. Materials, textures and meshes are
added to the according vectors of SLScene for later deallocation.
*/
SLNode* SLAssimpImporter::load(SLstring file,           //!< File with path or on default path
                               SLbool loadMeshesOnly,   //!< Only load nodes with meshes
                               SLuint flags)            //!< Import flags (see assimp/postprocess.h)
{
    // clear the intermediate data
    clear();

    // Check existance
    if (!SLFileSystem::fileExists(file))
    {   file = defaultPath + file;
        if (!SLFileSystem::fileExists(file))
        {   SLstring msg = "SLAssimpImporter: File not found: " + file + "\n";
            SL_WARN_MSG(msg.c_str());
            return nullptr;
        }
    }

    // Import file with assimp importer
    Assimp::Importer ai;
    const aiScene* scene = ai.ReadFile(file.c_str(), (SLuint)flags);
    if (!scene)
    {   SLstring msg = "Failed to load file: " + file + "\n" + ai.GetErrorString() + "\n";
        SL_WARN_MSG(msg.c_str());
        return nullptr;
    }

    // initial scan of the scene
    performInitialScan(scene);

    // load skeleton
    loadSkeleton(nullptr, _skeletonRoot);

    // load materials
    SLstring modelPath = SLUtils::getPath(file);
    SLVMaterial materials;
    for(SLint i = 0; i < (SLint)scene->mNumMaterials; i++)
        materials.push_back(loadMaterial(i, scene->mMaterials[i], modelPath));

    // load meshes & set their material
    std::map<int, SLMesh*> meshMap;  // map from the ai index to our mesh
    for(SLint i = 0; i < (SLint)scene->mNumMeshes; i++)
    {   SLMesh* mesh = loadMesh(scene->mMeshes[i]);
        if (mesh != 0)
        {   mesh->mat = materials[scene->mMeshes[i]->mMaterialIndex];
            _meshes.push_back(mesh);
            meshMap[i] = mesh;
        } else SL_LOG("SLAsssimpImporter::load failed: %s\nin path: %s\n", file.c_str(), modelPath.c_str());
    }

    // load the scene nodes recursively
    _sceneRoot = loadNodesRec(nullptr, scene->mRootNode, meshMap, loadMeshesOnly);

    // load animations
    vector<SLAnimation*> animations;
    for (SLint i = 0; i < (SLint)scene->mNumAnimations; i++)
        animations.push_back(loadAnimation(scene->mAnimations[i]));

    logMessage(LV_minimal, "\n---------------------------\n\n");

    return _sceneRoot;
}