#include "../../config.h"
#include "openfile_dialog.h"
+#include "../storage/storage.h"
#include "../i18n.h"
+extern GtkDrawingArea * drawing_area;
+
void openfile_dialog() {
GtkFileChooserDialog *dialog;
char *filename = NULL;
result = gedcom_parse_file(filename);
+ /* File is parsed, so we can calculate positions for loaded users. */
+ familia_storage_calc_positions(familia_storage_get_current());
+
g_free (filename);
+
+ gtk_widget_queue_draw(GTK_WIDGET(drawing_area));
}
gtk_widget_destroy(GTK_WIDGET(dialog));
#include <GL/gl.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "camera.h"
#include "../storage/storage.h"
+#include "../storage/positions.h"
-GLdouble camera_pos_x = 0;
-GLdouble camera_pos_y = 0;
-GLdouble camera_pos_z = 0;
+struct position * _cam_pos = NULL;
-/**
- *
- */
-struct position * camera_position_reset()
+void camera_position_reset()
{
- /**/
+ if (!_cam_pos) {
+ _cam_pos = (struct position *)malloc(sizeof(struct position));
+ }
+ familia_position_center(_cam_pos);
+}
+
+void camera_position_free()
+{
+ if (_cam_pos) {
+ free(_cam_pos);
+ _cam_pos = NULL;
+ }
+}
+
+void camera_mv_h(float x)
+{
+ assert(_cam_pos != NULL);
+
+ _cam_pos->x = x;
+}
+
+void camera_mv_v(float y)
+{
+ assert(_cam_pos != NULL);
+
+ _cam_pos->y = y;
+}
+
+struct position * camera_get_position()
+{
+ if (_cam_pos == NULL) {
+ camera_position_reset();
+ }
+ return _cam_pos;
+}
+
+void camera_position_dump()
+{
+ struct position * pos = camera_get_position();
+ fprintf(stderr, "Camera: pos(%f, %f, %f)\n", pos->x, pos->y, pos->z);
}
\ No newline at end of file
--- /dev/null
+/****************************************************************************
+ * Familia Lignum - Genealogical program *
+ * Copyright (C) 2011-2012 Rafał Długołęcki <rafal@dlugolecki.net.pl> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; version 2 of the License. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License along *
+ * with this program; if not, write to the Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
+ * *
+ ****************************************************************************/
+
+#ifndef _FAMILIA_MATH_CAMERA_H
+#define _FAMILIA_MATH_CAMERA_H
+
+#include "3d.h"
+
+/**
+ * @file camera.h
+ * @brief Functions for manipulating the camera.
+ */
+
+/**
+ * Calculates position of the camera and sets it as the current position.
+ * You have to invoke this function before any other, related to camera.
+ */
+void camera_position_reset();
+
+/**
+ * Free's memory related to the camera.
+ */
+void camera_position_free();
+
+/**
+ * Moves camera horizontally.
+ *
+ * Given parameter is absolute value on X axis. It means, that if current camera
+ * position is: (2,2,2), invoking this function with x=10, results in: (10,2,2)
+ *
+ * @param x New camera position on X axis
+ */
+void camera_mv_h(float x);
+
+/**
+ * Moves camera vertically.
+ *
+ * Given parameter is absolute value on Y axis. It means, that if current camera
+ * position is: (2,2,2), invoking this function with y=10, results in: (2,10,2)
+ *
+ * @param y New camera position on Y axis
+ */
+void camera_mv_v(float y);
+
+/**
+ * Returns current position of the camera.
+ *
+ * @return global position of the camera
+ */
+struct position * camera_get_position();
+
+/**
+ * Dumps informations on current status of the camera.
+ */
+void camera_position_dump();
+
+#endif /* _FAMILIA_MATH_CAMERA_H */
#include <stdlib.h>
#include <math.h>
+#include <assert.h>
#include "positions.h"
#include "yearline.h"
-#include "storage/individual.h"
-#include "storage/family.h"
+#include "../storage/individual.h"
+#include "../storage/family.h"
+#include "../storage/positions.h"
+#include "../storage/storage.h"
#include "../debug.h"
unsigned int children_no = 1;
int nth = 0;
+ assert(individual != NULL);
+
+ pos = (struct position *)malloc(sizeof(struct position));
+ pos->x = 0;
+ pos->y = 0;
+ pos->z = 0;
+
parents = familia_individual_get_parents(individual);
if (parents == NULL) {
+ fprintf(stderr, "No parents found, guess correct position (%f,%f,%f)\n", pos->x, pos->y, pos->z);
debug("TODO: Calculate position for root individual.");
- return NULL;
+ return pos;
}
nth = familia_individual_nth_child_of_family(individual, parents);
return NULL;
}
- pos = (struct position *)malloc(sizeof(struct position));
- pos->x = 0;
- pos->y = 0;
- pos->z = 0;
-
/* If there is only one child in family, place it vertically
* over the family (do not change x and z). For all other
* calculate these positions.
theta = FAMILY_AVAIL_RANGE / children_no;
/* We subtract from FAMILY_AVAIL_RANGE (e.g. 180),
- * to count angle from left instead of from right.
- * This makes oldest children display in this order.
- */
+ * to count angle from left instead of from right.
+ * This makes oldest children display in this order.
+ */
alpha = FAMILY_AVAIL_RANGE - theta * nth;
pos->x = cos(alpha);
}
/* pos.y is a local coordinate now. */
- pos->y = convert_date_to_height(NULL);
+ if (individual->birth) {
+ float average = 0;
+ average = familia_storage_get_individual_avr_yr(familia_storage_get_current());
+
+ pos->y = convert_date_to_height(individual->birth) - average;
+ }
+ else {
+ debug("birth == NULL, set y=yr_avg => return pos->y=0");
+ pos->y = 0;
+ }
return pos;
}
#include "yearline.h"
+#include "../storage/positions.h"
int convert_date_to_height(struct date_value *dv)
{
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
#include "individual.h"
{
unsigned int i = 0;
+ assert(individual != NULL);
+
if (individual->first_name) {
free(individual->first_name);
individual->first_name = NULL;
void familia_individual_set_first_name(struct familia_individual * individual, char * first_name)
{
+ assert(individual != NULL);
+
/* Remove old data if it exists */
if (individual->first_name) {
free(individual->first_name);
char * familia_individual_get_first_name(struct familia_individual * individual)
{
+ assert(individual != NULL);
+
return individual->first_name;
}
void familia_individual_set_last_name(struct familia_individual * individual, char * last_name)
{
+ assert(individual != NULL);
+
/* Remove old data if it exists */
if (individual->last_name) {
free(individual->last_name);
char * familia_individual_get_last_name(struct familia_individual * individual)
{
+ assert(individual != NULL);
+
return individual->last_name;
}
void familia_individual_add_family(struct familia_individual * individual, struct familia_family * family)
{
struct familia_family ** tmp = NULL;
- int size = (individual->families_no + 1);
+ int size = 0;
+ assert(individual != NULL);
+ assert(family != NULL);
+
+ size = (individual->families_no + 1);
tmp = realloc(individual->families, size * sizeof(struct familia_family *));
if (tmp) {
struct familia_family * familia_individual_get_family_by_id(struct familia_individual * individual, unsigned int id)
{
+ assert(individual != NULL);
+
if (individual->families_no < id) {
debug("Trying to get not existing family!\n");
return NULL;
int found = 0;
struct familia_family ** tmp = NULL;
+ assert(individual != NULL);
+
if (individual->families_no < id) {
debug("Trying to remove not existing family!\n");
return;
void familia_individual_set_parents(struct familia_individual * individual, struct familia_family * family)
{
+ assert(individual != NULL);
+
individual->parents = family;
}
struct familia_family * familia_individual_get_parents(struct familia_individual * individual)
{
+ assert(individual != NULL);
+
return individual->parents;
}
void familia_individual_remove_parents(struct familia_individual * individual)
{
+ assert(individual != NULL);
+
individual->parents = NULL;
}
int familia_individual_nth_child_of_family(struct familia_individual * individual, struct familia_family * family)
{
unsigned int i;
- unsigned int children_no = family->children_no;
- for (i = 0; i < children_no; i++) {
+ assert(individual != NULL);
+ assert(family != NULL);
+
+ for (i = 0; i < family->children_no; i++) {
if (family->children[i]->id == individual->id) {
return i;
}
void familia_individual_set_birth_date(struct familia_individual * individual, struct date_value dv)
{
+ assert(individual != NULL);
+
/* TODO: Add multiple birth dates (in case there are many different sources) */
if (!individual->birth) {
struct date_value * date = NULL;
else {
fprintf(stderr, "> Date has been already set, ignoring new one: %s\n", gedcom_date_to_string(&dv));
}
+}
+
+int familia_individual_get_birth_year(struct familia_individual * individual)
+{
+ assert(individual != NULL);
+
+ return individual->birth->date1.year;
}
\ No newline at end of file
*/
void familia_individual_set_birth_date(struct familia_individual * individual, struct date_value dv);
+int familia_individual_get_birth_year(struct familia_individual * individual);
+
#endif /*_FAMILIA_INDIVIDUAL_H */
#include "../debug.h"
#include "positions.h"
+#include "storage.h"
/**
* Structure holding individual and position pair
*
* Example graphic object is an individual or family...
*/
-struct familia_storage_positions * storage_positions;
+struct familia_storage_positions * storage_positions = NULL;
/**
* Initializes storage for individual and family positions.
{
if (!storage_positions) {
storage_positions = malloc(sizeof(struct familia_storage_positions));
-
+
if (!storage_positions) {
debug("["__FILE__ "] There was a problem with allocating memory for storage of positions.\n");
}
else {
+ storage_positions->individuals = NULL;
storage_positions->individuals_no = 0;
+ storage_positions->families = NULL;
storage_positions->families_no = 0;
}
}
void _familia_storage_positions_free()
{
if (storage_positions) {
+ unsigned int i;
+
if (storage_positions->individuals) {
+ for (i = 0; i < storage_positions->individuals_no; i++) {
+ free(storage_positions->individuals[i]);
+ }
free(storage_positions->individuals);
+ storage_positions->individuals_no = 0;
}
if (storage_positions->families) {
+ for (i = 0; i < storage_positions->families_no; i++) {
+ free(storage_positions->families[i]);
+ }
free(storage_positions->families);
+ storage_positions->families_no = 0;
}
free(storage_positions);
void _familia_positions_add_individual_position(struct familia_individual *individual, struct position *pos)
{
struct familia_storage_individual_position ** tmp = NULL;
+ struct familia_storage_individual_position * ind_pos = NULL;
unsigned int alloc_size = sizeof(struct familia_storage_individual_position *);
- int size = (storage_positions->individuals_no + 1);
+ int size = 0;
+
+ assert(storage_positions != NULL);
+
+ size = (storage_positions->individuals_no + 1);
+
+ ind_pos = malloc(sizeof(struct familia_storage_individual_position));
+
+ if (!ind_pos) {
+ debug("There was a problem with allocating memory for individual<->position pair");
+ return;
+ }
tmp = realloc(storage_positions->individuals, size * alloc_size);
if (tmp) {
storage_positions->individuals = tmp;
- storage_positions->individuals[storage_positions->individuals_no]->ind = individual;
- storage_positions->individuals[storage_positions->individuals_no]->pos = pos;
+
+ ind_pos->ind = individual;
+ ind_pos->pos = pos;
+
+ storage_positions->individuals[storage_positions->individuals_no] = ind_pos;
storage_positions->individuals_no++;
}
else {
debug("There were problems with allocating memory for storage of individual positions->\n");
+ free(ind_pos);
}
}
unsigned int i;
unsigned int id;
- /*
- * Uninitialized global. Return error.
- */
- if (!storage_positions || !storage_positions->individuals) {
- debug("Trying to request individual position, but positions storage is not initialized.\n");
- return NULL;
- }
+ assert(storage_positions != NULL);
+ assert(storage_positions->individuals != NULL);
id = individual->id;
unsigned int i;
unsigned int id;
- /*
- * Uninitialized global. Return error.
- */
- if (!storage_positions || !storage_positions->families) {
- debug("Trying to request family position, but positions storage is not initialized.\n");
- return NULL;
- }
+ assert(storage_positions != NULL);
+ assert(storage_positions->families != NULL);
id = family->id;
* Entry not found for a given individual. Return error.
*/
return NULL;
+}
+
+void familia_position_center(struct position * pos)
+{
+ assert(pos != NULL);
+
+ pos->x = 0;
+ pos->y = 0;
+ pos->z = 0;
}
\ No newline at end of file
*/
struct position * familia_position_get_family_position(struct familia_family *family);
+void familia_position_center(struct position * pos);
+
#endif /* _FAMILIA_STORAGE_POSITIONS_H */
#include <stdio.h>
#include <stdlib.h>
+#include <assert.h>
#include "storage.h"
+#include "positions.h"
#include "../debug.h"
struct familia_storage * _familia_storage_current;
+extern struct familia_storage_positions * storage_positions;
extern void _familia_storage_positions_init();
extern void _familia_storage_positions_free();
+extern void _familia_positions_add_individual_position(struct familia_individual *individual, struct position *pos);
+extern void _familia_positions_add_family_position(struct familia_family *family, struct position *pos);
struct familia_storage * familia_storage_get_current()
{
storage->families = NULL;
storage->families_no = 0;
-/* _familia_storage_positions_init();*/
+ _familia_storage_positions_init();
return storage;
}
storage->families_no = 0;
}
-/* _familia_storage_positions_free();*/
+ _familia_storage_positions_free();
}
void familia_storage_add_individual(struct familia_storage * storage, struct familia_individual * individual)
}
}
+float familia_storage_get_individual_avr_yr(struct familia_storage * storage) {
+ float result = 0;
+ float average = 0;
+ unsigned int average_no = 0;
+ unsigned int i;
+ struct familia_individual * individual = NULL;
+
+ assert(storage != NULL);
+
+ for (i = 0; i < storage->individuals_no; i++) {
+ individual = storage->individuals[i];
+
+ if (individual->birth != NULL) {
+ int year = familia_individual_get_birth_year(individual);
+ average += year;
+ average_no++;
+ }
+ }
+
+ if (average_no > 0) {
+ result = (float)average / (float)average_no;
+ }
+
+ return result;
+}
+void familia_storage_calc_positions(struct familia_storage * storage)
+{
+ unsigned int i;
+ struct position * pos = NULL;
+ struct familia_individual * individual = NULL;
+
+ assert(storage != NULL);
+
+ debug("Calculating positions");
+ for (i = 0; i < storage->individuals_no; i++) {
+ individual = storage->individuals[i];
+ pos = calculate_individual_position(individual);
+ fprintf(stderr, "CalcPos: (%f, %f. %f)\n", pos->x, pos->y, pos->z);
+ _familia_positions_add_individual_position(individual, pos);
+ }
+ debug("All positions has been calculated");
+}
+
void familia_storage_dump_all()
{
unsigned int i;
}
}
}
-}
+}
\ No newline at end of file
#include "individual.h"
#include "family.h"
+#include "positions.h"
/**
* @file storage.h
*/
void familia_storage_remove_family_by_id(struct familia_storage * storage, unsigned int id);
+float familia_storage_get_individual_avr_yr(struct familia_storage * storage);
+
+void familia_storage_calc_positions(struct familia_storage * storage);
+
void familia_storage_dump_all();
#endif /*_FAMILIA_STORAGE_H */
+#include <stdio.h>
#include <gtk/gtk.h>
#include <gtk/gtkgl.h>
#include <GL/gl.h>
#include "../debug.h"
#include "drawing_area.h"
+#include "../math/3d.h"
+#include "../math/camera.h"
#include "../graphics/constants.h"
#include "../graphics/individual.h"
#include "../graphics/family.h"
#include "../storage/storage.h"
-
-extern GLdouble camera_pos_x;
-extern GLdouble camera_pos_y;
-extern GLdouble camera_pos_z;
+#include "../storage/positions.h"
GtkDrawingArea * drawing_area = NULL;
unsigned int i;
unsigned int individuals_no;
unsigned int families_no;
+ float x, z;
+ float avr_ind_yr = 0;
+ struct position * pos = NULL;
+ struct position * cam_pos = NULL;
+ struct familia_individual * individual = NULL;
+ struct familia_storage * storage = NULL;
/*** OpenGL BEGIN ***/
if (!gtk_widget_begin_gl (widget)) {
return FALSE;
}
+ cam_pos = camera_get_position();
+ storage = familia_storage_get_current();
+
glMatrixMode (GL_MODELVIEW);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity ();
- gluLookAt (camera_pos_x, camera_pos_y, camera_pos_z, 0.0, 0.0, -100.0, 0.0, 1.0, 0.0);
+ /*Z+10, because we want to move camera backwards, to see rendered objects. */
+ gluLookAt (cam_pos->x, cam_pos->y, cam_pos->z + 10, 0.0, 0.0, -100.0, 0.0, 1.0, 0.0);
+ camera_position_dump();
- individuals_no = familia_storage_get_current()->individuals_no;
+ individuals_no = storage->individuals_no;
for (i = 0; i < individuals_no; i++) {
+ individual = familia_storage_get_individual_by_id(storage, i);
+ pos = calculate_individual_position(individual);
+ pos->x *= (GR_IND_RADIUS + 1)*10;
+ /* TODO: For now many individuals without birth date, or root ones will be positioned on (0,0,0). Fix algorithm.. */
+ /*
+ fprintf(stderr, "ind(%d) calc-pos: x:%f, z:%f\n", i, pos->x, pos->z);
+ fprintf(stderr, "ind(%d) hard-pos: x:%f, z:%f\n", i, x, z);
+ */
glPushMatrix ();
- glTranslatef(i * (GR_IND_RADIUS + 1), 0, -10);
+ glTranslatef(pos->x, pos->y, pos->z);
glColor3f (1.0, 1.0, 1.0);
graphics_render_individual();
glPopMatrix ();
}
- families_no = familia_storage_get_current()->families_no;
+ families_no = storage->families_no;
for (i = 0; i < families_no; i++) {
glPushMatrix ();
- glTranslatef(i * (GR_FAM_RADIUS + 1), -3, -10);
+ glTranslatef(i * (GR_FAM_RADIUS + 1), -3, 0);
glColor3f (1.0, 1.0, 1.0);
graphics_render_family();
glPopMatrix ();
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
+ camera_position_reset();
+
gtk_widget_end_gl (widget, FALSE);
/*** OpenGL END ***/
*/
void drawing_area_unrealize (GtkWidget *widget, gpointer data)
{
- /* Code */
+ camera_position_free();
}
#include <stdio.h>
#include <GL/gl.h>
+#include "../math/camera.h"
#include "scrollbars.h"
-extern GLdouble camera_pos_x;
-extern GLdouble camera_pos_y;
-extern GLdouble camera_pos_z;
-
extern GtkDrawingArea * drawing_area;
void horizontal_scrollbar_changed (GtkAdjustment *adjustment, gpointer user_data)
void horizontal_scrollbar_value_changed (GtkAdjustment *adjustment, gpointer user_data)
{
- //gdk_window_invalidate_rect(gtk_widget_get_window (adjustment), NULL, TRUE);
- camera_pos_x = gtk_adjustment_get_value(adjustment);
- fprintf (stderr, "HS_value_changed, camera_pos_x: %f\n", camera_pos_x);
+ float x = gtk_adjustment_get_value(adjustment);
+
+ camera_mv_h(x);
+ fprintf (stderr, "HS_value_changed, camera_pos_x: %f\n", x);
gtk_widget_queue_draw(GTK_WIDGET(drawing_area));
}
void vertical_scrollbar_value_changed (GtkAdjustment *adjustment, gpointer user_data)
{
- //gdk_window_invalidate_rect(gtk_widget_get_window (adjustment), NULL, TRUE);
- camera_pos_y = -gtk_adjustment_get_value(adjustment);
- fprintf (stderr, "VS_value_changed, camera_pos_y: %f\n", camera_pos_y);
+ float y = -gtk_adjustment_get_value(adjustment);
+
+ camera_mv_v(y);
+ fprintf (stderr, "VS_value_changed, camera_pos_y: %f\n", y);
gtk_widget_queue_draw(GTK_WIDGET(drawing_area));
}
\ No newline at end of file