/*
 * object.h
 *
 * Copyright (C) 1989, 1991, Craig E. Kolb
 * All rights reserved.
 *
 * This software may be freely copied, modified, and redistributed
 * provided that this copyright notice is preserved on all copies.
 *
 * You may not distribute this software, in whole or in part, as part of
 * any commercial product without the express consent of the authors.
 *
 * There is no warranty or other guarantee of fitness of this software
 * for any purpose.  It is provided solely "as is".
 *
 * $Id$
 *
 * $Log$
 */
#ifndef OBJECT_H
#define OBJECT_H

#include "libcommon/common.h"
#include "libcommon/transform.h"
#include "bounds.h"

/*
 * Constants for enter flag in HitNode.
 */
#define EXITING		1
#define ENTERING	2

#define MAXMODELDEPTH	128		/* Maximum height of DAG. */

typedef char * ObjRef;
typedef ObjRef ObjCreateFunc();

/*
 * If the object has a convert method, it's an aggregate
 * otherwise it's a primitive.
 */
#define IsAggregate(o)		((o)->methods->convert != NULL)

/*
 * Object methods.
 * (p) means applies only to primitive objects
 * (a) means applies only to aggregate objects
 */
typedef struct Methods {
	char		*(*name)();		/* Object name */
	ObjRef		(*create)();		/* Create and return ref */
	int		(*intersect)(),		/* Ray/obj intersection */
			(*normal)(),		/* Object normal (p) */
			(*enter)(),		/* Ray enter or exit? (p) */
			(*convert)();		/* Convert from list (a) */
	void		(*uv)(),		/* 2D mapping (p) */
			(*stats)(),		/* Statistics */
			(*bounds)();		/* Bounding volume */
	struct Methods	*(*methods)();		/* object methods func. */
	char		checkbounds,		/* check bbox before int.? */
			closed;			/* properly closed? */
} Methods;

/*
 * Object definition
 */
typedef struct Object {
	char *name;			/* Object name, if any. */
	ObjRef obj;			/* Pointer to object info. */
	Methods *methods;
	unsigned long prims;		/* sum of # primitive objects */
	Float bounds[2][3];		/* Bounding box */
	struct Surface *surf;		/* surface, if any */
	struct Trans *trans;		/* Transformation information */
	struct Texture *texture;	/* Texture mapping info. */
#ifdef SHAREDMEM
	unsigned long *counter;		/* Objs are shared, counters aren't */
#else
	unsigned long counter;		/* "mailbox" for grid intersection */
#endif
	struct Object *next;		/* Next object. */
} Object;

/*
 * Linked list of pointers to objects.
 */
typedef struct ObjList {
	Object *obj;
	struct ObjList *next;
} ObjList;

/*
 * Array of hit information.  Stores a path through an object DAG,
 * as well as the ray in 'model' (object) space and the distance from
 * the ray origin to the point of intersection.
 */
typedef struct HitNode {
	Object	*obj;			/* Object hit */
	Ray	ray;			/* Ray */
	Float	mindist;		/* Amount of ray to ignore */
	Float	dist;			/* Distance from ray origin to hit */
	int	enter;			/* Enter (TRUE) or Leave (FALSE) obj */
} HitNode;

/*
 * Structure holding a list of HitNodes.  A maximum of MAXMODELDEPTH
 * nodes can be referenced.
 */
typedef struct HitList {
	int nodes;
	HitNode data[MAXMODELDEPTH];
} HitList;

extern char	*ObjectName();

extern Object	*ObjCreate(), *ObjectCopy(), *ObjectCopyNamed(),
		*BoundsFind();


extern ObjList	*ObjStackPush(), *ObjStackPop();

extern void 	PrimUV(), AggregatePrintInfo(),
		IntersectStats();

extern int	AggregateConvert(), PrimNormal(), ObjectBounds(),
		TraceRay();	/* application-provided */

extern Methods	*MethodsCreate();

#endif /* OBJECT_H */
