Lib3dsSpotlightNode* lib3ds_node_new_spotlight(Lib3dsLight *light) { Lib3dsNode *node; Lib3dsSpotlightNode *n; assert(light); node = lib3ds_node_new(LIB3DS_NODE_SPOTLIGHT); strcpy(node->name, light->name); n = (Lib3dsSpotlightNode*)node; lib3ds_track_resize(&n->pos_track, 1); lib3ds_vector_copy(n->pos_track.keys[0].value, light->position); lib3ds_track_resize(&n->color_track, 1); lib3ds_vector_copy(n->color_track.keys[0].value, light->color); lib3ds_track_resize(&n->hotspot_track, 1); n->hotspot_track.keys[0].value[0] = light->hotspot; lib3ds_track_resize(&n->falloff_track, 1); n->falloff_track.keys[0].value[0] = light->falloff; lib3ds_track_resize(&n->roll_track, 1); n->roll_track.keys[0].value[0] = light->roll; return n; }
void lib3ds_file_create_nodes_for_meshes(Lib3dsFile *file) { Lib3dsNode *p; int i; for (i = 0; i < file->nmeshes; ++i) { Lib3dsMesh *mesh = file->meshes[i]; p = lib3ds_node_new(LIB3DS_NODE_MESH_INSTANCE); strcpy(p->name, mesh->name); lib3ds_file_insert_node(file, p, NULL); } }
Lib3dsCameraNode* lib3ds_node_new_camera(Lib3dsCamera *camera) { Lib3dsNode *node = lib3ds_node_new(LIB3DS_NODE_CAMERA); Lib3dsCameraNode *n; assert(camera); node = lib3ds_node_new(LIB3DS_NODE_CAMERA); strcpy(node->name, camera->name); n = (Lib3dsCameraNode*)node; lib3ds_track_resize(&n->pos_track, 1); lib3ds_vector_copy(n->pos_track.keys[0].value, camera->position); lib3ds_track_resize(&n->fov_track, 1); n->fov_track.keys[0].value[0] = camera->fov; lib3ds_track_resize(&n->roll_track, 1); n->roll_track.keys[0].value[0] = camera->roll; return n; }
Lib3dsTargetNode* lib3ds_node_new_spotligf_target(Lib3dsLight *light) { Lib3dsNode *node; Lib3dsTargetNode *n; assert(light); node = lib3ds_node_new(LIB3DS_NODE_SPOTLIGHT_TARGET); strcpy(node->name, light->name); n = (Lib3dsTargetNode*)node; lib3ds_track_resize(&n->pos_track, 1); lib3ds_vector_copy(n->pos_track.keys[0].value, light->target); return n; }
Lib3dsTargetNode* lib3ds_node_new_camera_target(Lib3dsCamera *camera) { Lib3dsNode *node; Lib3dsTargetNode *n; assert(camera); node = lib3ds_node_new(LIB3DS_NODE_CAMERA_TARGET); strcpy(node->name, camera->name); n = (Lib3dsTargetNode*)node; lib3ds_track_resize(&n->pos_track, 1); lib3ds_vector_copy(n->pos_track.keys[0].value, camera->target); return n; }
Lib3dsAmbientColorNode* lib3ds_node_new_ambient_color(float color0[3]) { Lib3dsNode *node; Lib3dsAmbientColorNode *n; node = lib3ds_node_new(LIB3DS_NODE_AMBIENT_COLOR); n = (Lib3dsAmbientColorNode*)node; lib3ds_track_resize(&n->color_track, 1); if (color0) { lib3ds_vector_copy(n->color_track.keys[0].value, color0); } else { lib3ds_vector_zero(n->color_track.keys[0].value); } return n; }
Lib3dsOmnilightNode* lib3ds_node_new_omnilight(Lib3dsLight *light) { Lib3dsNode *node; Lib3dsOmnilightNode *n; assert(light); node = lib3ds_node_new(LIB3DS_NODE_OMNILIGHT); strcpy(node->name, light->name); n = (Lib3dsOmnilightNode*)node; lib3ds_track_resize(&n->pos_track, 1); lib3ds_vector_copy(n->pos_track.keys[0].value, light->position); lib3ds_track_resize(&n->color_track, 1); lib3ds_vector_copy(n->color_track.keys[0].value, light->color); return n; }
Lib3dsMeshInstanceNode* lib3ds_node_new_mesh_instance(Lib3dsMesh *mesh, const char *instance_name, float pos0[3], float scl0[3], float rot0[4]) { Lib3dsNode *node; Lib3dsMeshInstanceNode *n; int i; node = lib3ds_node_new(LIB3DS_NODE_MESH_INSTANCE); if (mesh) { strcpy(node->name, mesh->name); } else { strcpy(node->name, "$$$DUMMY"); } n = (Lib3dsMeshInstanceNode*)node; if (instance_name) { strcpy(n->instance_name, instance_name); } lib3ds_track_resize(&n->pos_track, 1); if (pos0) { lib3ds_vector_copy(n->pos_track.keys[0].value, pos0); } lib3ds_track_resize(&n->scl_track, 1); if (scl0) { lib3ds_vector_copy(n->scl_track.keys[0].value, scl0); } else { lib3ds_vector_make(n->scl_track.keys[0].value, 1, 1, 1); } lib3ds_track_resize(&n->rot_track, 1); if (rot0) { for (i = 0; i < 4; ++i) n->rot_track.keys[0].value[i] = rot0[i]; } else { for (i = 0; i < 4; ++i) n->rot_track.keys[0].value[i] = 0; } return n; }
/*! * Load the model from .3ds file. */ static void load_model(void) { file = lib3ds_file_open(filepath); if (!file) { puts("3dsplayer: Error: Loading 3DS file failed.\n"); exit(1); } /* No nodes? Fabricate nodes to display all the meshes. */ if (!file->nodes) { Lib3dsNode *node; int i; for (i = 0; i < file->nmeshes; ++i) { Lib3dsMesh *mesh = file->meshes[i]; node = lib3ds_node_new(LIB3DS_NODE_MESH_INSTANCE); strcpy(node->name, mesh->name); lib3ds_file_insert_node(file, node, NULL); } } lib3ds_file_eval(file, 0.0f); lib3ds_file_bounding_box_of_nodes(file, 1, 0, 0, bmin, bmax, NULL); sx = bmax[0] - bmin[0]; sy = bmax[1] - bmin[1]; sz = bmax[2] - bmin[2]; size = MAX(sx, sy); size = MAX(size, sz); cx = (bmin[0] + bmax[0]) / 2; cy = (bmin[1] + bmax[1]) / 2; cz = (bmin[2] + bmax[2]) / 2; /* No cameras in the file? Add four */ if (!file->ncameras) { /* Add some cameras that encompass the bounding box */ Lib3dsCamera *camera = lib3ds_camera_new("Camera_X"); camera->target[0] = cx; camera->target[1] = cy; camera->target[2] = cz; memcpy(camera->position, camera->target, sizeof(camera->position)); camera->position[0] = bmax[0] + 1.5 * MAX(sy, sz); camera->near_range = (camera->position[0] - bmax[0]) * .5; camera->far_range = (camera->position[0] - bmin[0]) * 2; lib3ds_file_insert_camera(file, camera, -1); /* Since lib3ds considers +Y to be into the screen, we'll put * this camera on the -Y axis, looking in the +Y direction. */ camera = lib3ds_camera_new("Camera_Y"); camera->target[0] = cx; camera->target[1] = cy; camera->target[2] = cz; memcpy(camera->position, camera->target, sizeof(camera->position)); camera->position[1] = bmin[1] - 1.5 * MAX(sx, sz); camera->near_range = (bmin[1] - camera->position[1]) * .5; camera->far_range = (bmax[1] - camera->position[1]) * 2; lib3ds_file_insert_camera(file, camera, -1); camera = lib3ds_camera_new("Camera_Z"); camera->target[0] = cx; camera->target[1] = cy; camera->target[2] = cz; memcpy(camera->position, camera->target, sizeof(camera->position)); camera->position[2] = bmax[2] + 1.5 * MAX(sx, sy); camera->near_range = (camera->position[2] - bmax[2]) * .5; camera->far_range = (camera->position[2] - bmin[2]) * 2; lib3ds_file_insert_camera(file, camera, -1); camera = lib3ds_camera_new("Camera_ISO"); camera->target[0] = cx; camera->target[1] = cy; camera->target[2] = cz; memcpy(camera->position, camera->target, sizeof(camera->position)); camera->position[0] = bmax[0] + .75 * size; camera->position[1] = bmin[1] - .75 * size; camera->position[2] = bmax[2] + .75 * size; camera->near_range = (camera->position[0] - bmax[0]) * .5; camera->far_range = (camera->position[0] - bmin[0]) * 3; lib3ds_file_insert_camera(file, camera, -1); } /* No lights in the file? Add some. */ if (!file->nlights) { Lib3dsLight *light; light = lib3ds_light_new("light0"); light->spot_light = 0; light->see_cone = 0; light->color[0] = light->color[1] = light->color[2] = .6; light->position[0] = cx + size * .75; light->position[1] = cy - size * 1.; light->position[2] = cz + size * 1.5; light->position[3] = 0.; light->outer_range = 100; light->inner_range = 10; light->multiplier = 1; lib3ds_file_insert_light(file, light, -1); light = lib3ds_light_new("light1"); light->spot_light = 0; light->see_cone = 0; light->color[0] = light->color[1] = light->color[2] = .3; light->position[0] = cx - size; light->position[1] = cy - size; light->position[2] = cz + size * .75; light->position[3] = 0.; light->outer_range = 100; light->inner_range = 10; light->multiplier = 1; lib3ds_file_insert_light(file, light, -1); light = lib3ds_light_new("light2"); light->spot_light = 0; light->see_cone = 0; light->color[0] = light->color[1] = light->color[2] = .3; light->position[0] = cx; light->position[1] = cy + size; light->position[2] = cz + size; light->position[3] = 0.; light->outer_range = 100; light->inner_range = 10; light->multiplier = 1; lib3ds_file_insert_light(file, light, -1); } camera = file->cameras[0]->name; lib3ds_file_eval(file, 0); }
static void kfdata_read(Lib3dsFile *file, Lib3dsIo *io) { Lib3dsChunk c; uint16_t chunk; unsigned num_nodes = 0; Lib3dsNode *last = NULL; lib3ds_chunk_read_start(&c, CHK_KFDATA, io); while ((chunk = lib3ds_chunk_read_next(&c, io)) != 0) { switch (chunk) { case CHK_KFHDR: { file->keyf_revision = lib3ds_io_read_word(io); lib3ds_io_read_string(io, file->name, 12 + 1); file->frames = lib3ds_io_read_intd(io); break; } case CHK_KFSEG: { file->segment_from = lib3ds_io_read_intd(io); file->segment_to = lib3ds_io_read_intd(io); break; } case CHK_KFCURTIME: { file->current_frame = lib3ds_io_read_intd(io); break; } case CHK_VIEWPORT_LAYOUT: case CHK_DEFAULT_VIEW: { lib3ds_chunk_read_reset(&c, io); lib3ds_viewport_read(&file->viewport_keyf, io); break; } case CHK_AMBIENT_NODE_TAG: case CHK_OBJECT_NODE_TAG: case CHK_CAMERA_NODE_TAG: case CHK_TARGET_NODE_TAG: case CHK_LIGHT_NODE_TAG: case CHK_SPOTLIGHT_NODE_TAG: case CHK_L_TARGET_NODE_TAG: { Lib3dsNodeType type = (Lib3dsNodeType)0; Lib3dsNode *node; switch (chunk) { case CHK_AMBIENT_NODE_TAG: type = LIB3DS_NODE_AMBIENT_COLOR; break; case CHK_OBJECT_NODE_TAG: type = LIB3DS_NODE_MESH_INSTANCE; break; case CHK_CAMERA_NODE_TAG: type = LIB3DS_NODE_CAMERA; break; case CHK_TARGET_NODE_TAG: type = LIB3DS_NODE_CAMERA_TARGET; break; case CHK_LIGHT_NODE_TAG: type = LIB3DS_NODE_OMNILIGHT; break; case CHK_SPOTLIGHT_NODE_TAG: type = LIB3DS_NODE_SPOTLIGHT; break; case CHK_L_TARGET_NODE_TAG: type = LIB3DS_NODE_SPOTLIGHT_TARGET; break; } node = lib3ds_node_new(type); node->node_id = (unsigned short)(num_nodes++); if (last) { last->next = node; } else { file->nodes = node; } node->user_ptr = last; last = node; lib3ds_chunk_read_reset(&c, io); lib3ds_node_read(node, io); break; } default: lib3ds_chunk_unknown(chunk, io); } } { Lib3dsNode **nodes = (Lib3dsNode**)malloc(num_nodes * sizeof(Lib3dsNode*)); unsigned i; Lib3dsNode *p, *q, *parent; p = file->nodes; for (i = 0; i < num_nodes; ++i) { nodes[i] = p; p = p->next; } qsort(nodes, num_nodes, sizeof(Lib3dsNode*), compare_node_id); p = last; while (p) { q = (Lib3dsNode*)p->user_ptr; if (p->user_id != 65535) { parent = *(Lib3dsNode**)bsearch(&p->user_id, nodes, num_nodes, sizeof(Lib3dsNode*), compare_node_id2); if (parent) { q->next = p->next; p->next = parent->childs; p->parent = parent; parent->childs = p; } else { /* TODO: warning */ } } p->user_id = 0; p->user_ptr = NULL; p = q; } free(nodes); } lib3ds_chunk_read_end(&c, io); }