/*! * Apply a rotation about an arbitrary axis to a matrix. * * \ingroup matrix */ void lib3ds_matrix_rotate_axis(Lib3dsMatrix m, Lib3dsVector axis, Lib3dsFloat angle) { Lib3dsQuat q; lib3ds_quat_axis_angle(q,axis,angle); lib3ds_matrix_rotate(m,q); }
/*! * \internal * * The objects created as children of \p parent will \em not be rotated or * translated correctly. Instead the required transformations are stored and * provided to the user, see \ref Loader3ds::getTransformationNodes */ bool Loader3dsInternal::loadNode(dcollide::World* world, dcollide::Proxy* parent, Lib3dsNode* node, Lib3dsMatrix* parentTranslateRotateMatrix) { if (!parent || !node) { return false; } if (node->type != LIB3DS_OBJECT_NODE) { return false; } Lib3dsObjectData* data = &node->data.object; Lib3dsMatrix translateRotateMatrix; lib3ds_matrix_copy(translateRotateMatrix, *parentTranslateRotateMatrix); lib3ds_matrix_translate(translateRotateMatrix, data->pos); lib3ds_matrix_rotate(translateRotateMatrix, data->rot); dcollide::Shape* shape = createShape(node, &translateRotateMatrix); dcollide::Proxy* object = world->createProxy(shape); mData->mProxy2TextureInformation.insert(std::make_pair(object, loadTextureInformation(node))); dcollide::Vector3 scale(data->scl[0], data->scl[1], data->scl[2]); dcollide::Vector3 translation(data->pos[0], data->pos[1], data->pos[2]); Lib3dsMatrix lib3dsRotationMatrix; lib3ds_matrix_identity(lib3dsRotationMatrix); lib3ds_matrix_rotate(lib3dsRotationMatrix, data->rot); dcollide::Matrix rotation(&lib3dsRotationMatrix[0][0]); Loader3ds::TransformationNode transformation; transformation.translation = translation; transformation.rotation = rotation; mData->mProxy2Transformation.insert(std::make_pair(object, transformation)); for (Lib3dsNode* n = node->childs; n; n = n->next) { if (!loadNode(world, object, n, &translateRotateMatrix)) { std::cerr << "Failed loading node " << n->name << std::endl; // TODO: delete object->getProxy() ? delete object; return false; } } parent->addChild(object); return true; }
/*! * Compute a camera matrix based on position, target and roll. * * Generates a translate/rotate matrix that maps world coordinates * to camera coordinates. Resulting matrix does not include perspective * transform. * * \param matrix Destination matrix. * \param pos Camera position * \param tgt Camera target * \param roll Roll angle */ void lib3ds_matrix_camera(float matrix[4][4], float pos[3], float tgt[3], float roll) { float M[4][4]; float x[3], y[3], z[3]; lib3ds_vector_sub(y, tgt, pos); lib3ds_vector_normalize(y); if (y[0] != 0. || y[1] != 0) { z[0] = 0; z[1] = 0; z[2] = 1.0; } else { /* Special case: looking straight up or down z axis */ z[0] = -1.0; z[1] = 0; z[2] = 0; } lib3ds_vector_cross(x, y, z); lib3ds_vector_cross(z, x, y); lib3ds_vector_normalize(x); lib3ds_vector_normalize(z); lib3ds_matrix_identity(M); M[0][0] = x[0]; M[1][0] = x[1]; M[2][0] = x[2]; M[0][1] = y[0]; M[1][1] = y[1]; M[2][1] = y[2]; M[0][2] = z[0]; M[1][2] = z[1]; M[2][2] = z[2]; lib3ds_matrix_identity(matrix); lib3ds_matrix_rotate(matrix, roll, 0, 1, 0); lib3ds_matrix_mult(matrix, matrix, M); lib3ds_matrix_translate(matrix, -pos[0], -pos[1], -pos[2]); }
/*! * Evaluate an animation node. * * Recursively sets node and its children to their appropriate values * for this point in the animation. * * \param node Node to be evaluated. * \param t time value, between 0. and file->frames * * \ingroup node */ void lib3ds_node_eval(Lib3dsNode *node, Lib3dsFloat t) { ASSERT(node); switch (node->type) { case LIB3DS_UNKNOWN_NODE: { ASSERT(LIB3DS_FALSE); } break; case LIB3DS_AMBIENT_NODE: { Lib3dsAmbientData *n=&node->data.ambient; if (node->parent) { lib3ds_matrix_copy(node->matrix, node->parent->matrix); } else { lib3ds_matrix_identity(node->matrix); } lib3ds_lin3_track_eval(&n->col_track, n->col, t); } break; case LIB3DS_OBJECT_NODE: { Lib3dsMatrix M; Lib3dsObjectData *n=&node->data.object; lib3ds_lin3_track_eval(&n->pos_track, n->pos, t); lib3ds_quat_track_eval(&n->rot_track, n->rot, t); if (n->scl_track.keyL) { lib3ds_lin3_track_eval(&n->scl_track, n->scl, t); } else { n->scl[0] = n->scl[1] = n->scl[2] = 1.0f; } lib3ds_bool_track_eval(&n->hide_track, &n->hide, t); lib3ds_morph_track_eval(&n->morph_track, n->morph, t); lib3ds_matrix_identity(M); lib3ds_matrix_translate(M, n->pos); lib3ds_matrix_rotate(M, n->rot); lib3ds_matrix_scale(M, n->scl); if (node->parent) { lib3ds_matrix_copy(node->matrix, node->parent->matrix); lib3ds_matrix_mult(node->matrix, M); } else { lib3ds_matrix_copy(node->matrix, M); } } break; case LIB3DS_CAMERA_NODE: { Lib3dsCameraData *n=&node->data.camera; lib3ds_lin3_track_eval(&n->pos_track, n->pos, t); lib3ds_lin1_track_eval(&n->fov_track, &n->fov, t); lib3ds_lin1_track_eval(&n->roll_track, &n->roll, t); if (node->parent) { lib3ds_matrix_copy(node->matrix, node->parent->matrix); } else { lib3ds_matrix_identity(node->matrix); } lib3ds_matrix_translate(node->matrix, n->pos); } break; case LIB3DS_TARGET_NODE: { Lib3dsTargetData *n=&node->data.target; lib3ds_lin3_track_eval(&n->pos_track, n->pos, t); if (node->parent) { lib3ds_matrix_copy(node->matrix, node->parent->matrix); } else { lib3ds_matrix_identity(node->matrix); } lib3ds_matrix_translate(node->matrix, n->pos); } break; case LIB3DS_LIGHT_NODE: { Lib3dsLightData *n=&node->data.light; lib3ds_lin3_track_eval(&n->pos_track, n->pos, t); lib3ds_lin3_track_eval(&n->col_track, n->col, t); lib3ds_lin1_track_eval(&n->hotspot_track, &n->hotspot, t); lib3ds_lin1_track_eval(&n->falloff_track, &n->falloff, t); lib3ds_lin1_track_eval(&n->roll_track, &n->roll, t); if (node->parent) { lib3ds_matrix_copy(node->matrix, node->parent->matrix); } else { lib3ds_matrix_identity(node->matrix); } lib3ds_matrix_translate(node->matrix, n->pos); } break; case LIB3DS_SPOT_NODE: { Lib3dsSpotData *n=&node->data.spot; lib3ds_lin3_track_eval(&n->pos_track, n->pos, t); if (node->parent) { lib3ds_matrix_copy(node->matrix, node->parent->matrix); } else { lib3ds_matrix_identity(node->matrix); } lib3ds_matrix_translate(node->matrix, n->pos); } break; } { Lib3dsNode *p; for (p=node->childs; p!=0; p=p->next) { lib3ds_node_eval(p, t); } } }