Example #1
0
File: assiqe.c Project: r-lyeh/eve
void bake_mesh_skin(const struct aiMesh *mesh)
{
	int i, k, b;
	struct aiMatrix3x3 mat3;
	struct aiMatrix4x4 bonemat[1000], mat;
	struct aiVector3D *outpos, *outnorm;

	if (mesh->mNumBones == 0)
		return;

	outpos = malloc(mesh->mNumVertices * sizeof *outpos);
	outnorm = malloc(mesh->mNumVertices * sizeof *outnorm);
	memset(outpos, 0, mesh->mNumVertices * sizeof *outpos);
	memset(outnorm, 0, mesh->mNumVertices * sizeof *outpos);

	calc_abs_pose();

	for (i = 0; i < mesh->mNumBones; i++) {
		b = find_bone(mesh->mBones[i]->mName.data);
		bonemat[i] = bonelist[b].abspose;
		aiMultiplyMatrix4(&bonemat[i], &mesh->mBones[i]->mOffsetMatrix);
	}

	for (k = 0; k < mesh->mNumBones; k++) {
		struct aiBone *bone = mesh->mBones[k];
		b = find_bone(mesh->mBones[k]->mName.data);
		mat = bonemat[k];
		mat3.a1 = mat.a1; mat3.a2 = mat.a2; mat3.a3 = mat.a3;
		mat3.b1 = mat.b1; mat3.b2 = mat.b2; mat3.b3 = mat.b3;
		mat3.c1 = mat.c1; mat3.c2 = mat.c2; mat3.c3 = mat.c3;
		for (i = 0; i < bone->mNumWeights; i++) {
			struct aiVertexWeight vw = bone->mWeights[i];
			int v = vw.mVertexId;
			float w = vw.mWeight;
			struct aiVector3D srcpos = mesh->mVertices[v];
			struct aiVector3D srcnorm = mesh->mNormals[v];
			aiTransformVecByMatrix4(&srcpos, &mat);
			aiTransformVecByMatrix3(&srcnorm, &mat3);
			outpos[v].x += srcpos.x * w;
			outpos[v].y += srcpos.y * w;
			outpos[v].z += srcpos.z * w;
			outnorm[v].x += srcnorm.x * w;
			outnorm[v].y += srcnorm.y * w;
			outnorm[v].z += srcnorm.z * w;
		}
	}

	memcpy(mesh->mVertices, outpos, mesh->mNumVertices * sizeof *outpos);
	memcpy(mesh->mNormals, outnorm, mesh->mNumVertices * sizeof *outnorm);

	free(outpos);
	free(outnorm);
}
Example #2
0
File: assiqe.c Project: r-lyeh/eve
void mark_skinned_bones(const struct aiScene *scene)
{
	int i, k, a, b;

	for (i = 0; i < numbones; i++) {
		struct aiNode *node = bonelist[i].node;

		if (only_one_node && strcmp(bonelist[i].clean_name, only_one_node))
			continue;

		for (k = 0; k < node->mNumMeshes; k++) {
			struct aiMesh *mesh = scene->mMeshes[node->mMeshes[k]];
			for (a = 0; a < mesh->mNumBones; a++) {
				b = find_bone(mesh->mBones[a]->mName.data);
				if (!bonelist[b].isbone) {
					bonelist[b].reason = "skinned";
					bonelist[b].invpose = mesh->mBones[a]->mOffsetMatrix;
					bonelist[b].isbone = 1;
					bonelist[b].isskin = 1;
				} else if (!need_to_bake_skin) {
					if (memcmp(&bonelist[b].invpose, &mesh->mBones[a]->mOffsetMatrix, sizeof bonelist[b].invpose))
						need_to_bake_skin = 1;
				}
			}
		}
	}
}
Example #3
0
File: assiqe.c Project: r-lyeh/eve
void mark_animated_bones(const struct aiScene *scene)
{
	int i, k, b;
	for (i = 0; i < scene->mNumAnimations; i++) {
		const struct aiAnimation *anim = scene->mAnimations[i];
		for (k = 0; k < anim->mNumChannels; k++) {
			b = find_bone(anim->mChannels[k]->mNodeName.data);
			bonelist[b].reason = "animated";
			bonelist[b].isbone = 1;
		}
	}
}
Example #4
0
void Skeleton::physical_bones_start_simulation_on(const Array &p_bones) {

	Vector<int> sim_bones;
	if (p_bones.size() <= 0) {
		sim_bones.push_back(0); // if no bones is specified, activate ragdoll on full body
	} else {
		sim_bones.resize(p_bones.size());
		int c = 0;
		for (int i = sim_bones.size() - 1; 0 <= i; --i) {
			if (Variant::STRING == p_bones.get(i).get_type()) {
				int bone_id = find_bone(p_bones.get(i));
				if (bone_id != -1)
					sim_bones.write[c++] = bone_id;
			}
		}
		sim_bones.resize(c);
	}

	_pb_start_simulation(this, this, sim_bones);
}
Example #5
0
File: assiqe.c Project: r-lyeh/eve
void export_frame(FILE *out, const struct aiAnimation *anim, int frame)
{
	int i;

	// start with fresh matrices
	apply_initial_frame();

	for (i = 0; i < anim->mNumChannels; i++) {
		struct aiNodeAnim *chan = anim->mChannels[i];
		int a = find_bone(chan->mNodeName.data);
		int tframe = MIN(frame, chan->mNumPositionKeys - 1);
		int rframe = MIN(frame, chan->mNumRotationKeys - 1);
		int sframe = MIN(frame, chan->mNumScalingKeys - 1);
		bonelist[a].translate = chan->mPositionKeys[tframe].mValue;
		bonelist[a].rotate = chan->mRotationKeys[rframe].mValue;
		bonelist[a].scale = chan->mScalingKeys[sframe].mValue;
#ifdef HACK_MATRIX_KEY
		bonelist[a].pose = chan->mRotationKeys[rframe].mMatrixValue;
#endif
	}

#ifndef HACK_MATRIX_KEY
	// translate/rotate/scale have changed: recompute pose
	for (i = 0; i < numbones; i++) {
		if (bonelist[i].isbone) {
			// make sure we're not hit by precision issues in decomposematrix
			aiNormalizeQuaternion(&bonelist[i].rotate);
			aiComposeMatrix(&bonelist[i].pose, &bonelist[i].scale, &bonelist[i].rotate, &bonelist[i].translate);
		}
	}
#endif

	fprintf(out, "\n");
	fprintf(out, "frame %d\n", frame);
	export_pose(out);
}
Example #6
0
Bone_CPtr BoneHierarchy::bones(const std::string& name) const
{
	return m_bones[find_bone(name)];
}
Example #7
0
File: assiqe.c Project: r-lyeh/eve
void export_node(FILE *out, const struct aiScene *scene, const struct aiNode *node,
	struct aiMatrix4x4 mat, char *clean_name)
{
	struct aiMatrix3x3 mat3;
	int i, a, k, t;

	aiMultiplyMatrix4(&mat, &node->mTransformation);
	mat3.a1 = mat.a1; mat3.a2 = mat.a2; mat3.a3 = mat.a3;
	mat3.b1 = mat.b1; mat3.b2 = mat.b2; mat3.b3 = mat.b3;
	mat3.c1 = mat.c1; mat3.c2 = mat.c2; mat3.c3 = mat.c3;

	if (!strstr(node->mName.data, "$ColladaAutoName$"))
		clean_name = clean_node_name((char*)node->mName.data);

	if (only_one_node && strcmp(clean_name, only_one_node))
		goto skip_mesh;

	for (i = 0; i < node->mNumMeshes; i++) {
		struct aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
		struct aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];

		if (mesh->mNumBones == 0 && dobone && !dorigid) {
			if (verbose)
				fprintf(stderr, "skipping rigid mesh %d in node %s (no bones)\n", i, clean_name);
			continue;
		}

		fprintf(stderr, "exporting mesh %s[%d]: %d vertices, %d faces\n",
				clean_name, i, mesh->mNumVertices, mesh->mNumFaces);

		fprintf(out, "\n");
		fprintf(out, "mesh \"%s\"\n", clean_name);
		fprintf(out, "material \"%s\"\n", find_material(material));

		struct vb *vb = (struct vb*) malloc(mesh->mNumVertices * sizeof(*vb));
		memset(vb, 0, mesh->mNumVertices * sizeof(*vb));

		// A rigidly animated node -- insert fake blend index/weights
		if (mesh->mNumBones == 0 && dobone) {
			a = find_bone((char*)node->mName.data);
			if (verbose)
				fprintf(stderr, "\trigid bone %d for mesh in node %s (no bones)\n", bonelist[a].number, node->mName.data);
			for (k = 0; k < mesh->mNumVertices; k++) {
				vb[k].b[0] = bonelist[a].number;
				vb[k].w[0] = 1;
				vb[k].n = 1;
			}
		}

		// Assemble blend index/weight array
		for (k = 0; k < mesh->mNumBones; k++) {
			struct aiBone *bone = mesh->mBones[k];
			a = find_bone(bone->mName.data);
			for (t = 0; t < bone->mNumWeights; t++) {
				struct aiVertexWeight *w = mesh->mBones[k]->mWeights + t;
				int idx = w->mVertexId;
				if (vb[idx].n < MAXBLEND) {
					vb[idx].b[vb[idx].n] = bonelist[a].number;
					vb[idx].w[vb[idx].n] = w->mWeight;
					vb[idx].n++;
				}
			}
		}

		for (k = 0; k < mesh->mNumVertices; k++) {
			struct aiVector3D vp = mesh->mVertices[k];
			if (!dobone)
				aiTransformVecByMatrix4(&vp, &mat);
			fprintf(out, "vp %.9g %.9g %.9g\n", vp.x, vp.y, vp.z);
			if (mesh->mNormals) {
				struct aiVector3D vn = mesh->mNormals[k];
				if (!dobone)
					aiTransformVecByMatrix3(&vn, &mat3);
				fprintf(out, "vn %.9g %.9g %.9g\n", vn.x, vn.y, vn.z);
			}

			if (mesh->mTextureCoords[0]) {
				float u = mesh->mTextureCoords[0][k].x;
				float v = 1 - mesh->mTextureCoords[0][k].y;
				fprintf(out, "vt %.9g %.9g\n", u, v);
			}
			for (t = 1; t <= MAX_UVMAP; t++) {
				if (mesh->mTextureCoords[t]) {
					float u = mesh->mTextureCoords[t][k].x;
					float v = 1 - mesh->mTextureCoords[t][k].y;
					fprintf(out, "v%d %.9g %.9g\n", FIRST_UVMAP+t-1, u, v);
				}
			}

			if (mesh->mColors[0]) {
				float r = mesh->mColors[0][k].r; r = floorf(r * 255) / 255;
				float g = mesh->mColors[0][k].g; g = floorf(g * 255) / 255;
				float b = mesh->mColors[0][k].b; b = floorf(b * 255) / 255;
				float a = mesh->mColors[0][k].a; a = floorf(a * 255) / 255;
				fprintf(out, "vc %.9g %.9g %.9g %.9g\n", r, g, b, a);
			}
			for (t = 1; t <= MAX_COL; t++) {
				if (mesh->mColors[t]) {
					float r = mesh->mColors[t][k].r; r = floorf(r * 255) / 255;
					float g = mesh->mColors[t][k].g; g = floorf(g * 255) / 255;
					float b = mesh->mColors[t][k].b; b = floorf(b * 255) / 255;
					float a = mesh->mColors[t][k].a; a = floorf(a * 255) / 255;
					fprintf(out, "v%d %.9g %.9g %.9g %.9g\n", FIRST_COL+t-1, r, g, b, a);
				}
			}

			if (dobone) {
				fprintf(out, "vb");
				for (t = 0; t < vb[k].n; t++) {
					fprintf(out, " %d %.9g", vb[k].b[t], vb[k].w[t]);
				}
				fprintf(out, "\n");
			}
		}

		for (k = 0; k < mesh->mNumFaces; k++) {
			struct aiFace *face = mesh->mFaces + k;
			if (face->mNumIndices == 3) {
				if (doflip)
					fprintf(out, "fm %d %d %d\n", face->mIndices[2], face->mIndices[1], face->mIndices[0]);
				else
					fprintf(out, "fm %d %d %d\n", face->mIndices[0], face->mIndices[1], face->mIndices[2]);
			} else if (face->mNumIndices == 4) {
				if (doflip)
					fprintf(out, "fm %d %d %d %d\n", face->mIndices[3], face->mIndices[2], face->mIndices[1], face->mIndices[0]);
				else
					fprintf(out, "fm %d %d %d %d\n", face->mIndices[0], face->mIndices[1], face->mIndices[2], face->mIndices[3]);
			} else if (face->mNumIndices > 4) {
				fprintf(stderr, "n-gon (%d) in mesh!\n", face->mNumIndices);
				int i1 = face->mIndices[0];
				int i2 = face->mIndices[1];
				for (a = 2; a < face->mNumIndices; a++) {
					int i3 = face->mIndices[a];
					if (doflip)
						fprintf(out, "fm %d %d %d\n", i3, i2, i1);
					else
						fprintf(out, "fm %d %d %d\n", i1, i2, i3);
					i2 = i3;
				}
			} else {
				fprintf(stderr, "skipping point/line primitive\n");
			}
		}

		free(vb);
	}

skip_mesh:

	for (i = 0; i < node->mNumChildren; i++)
		export_node(out, scene, node->mChildren[i], mat, clean_name);
}