/*
 * objdef.c
 *
 * 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$
 */

#include "rayshade.h"
#include "options.h"
#include "stats.h"

static Object *Objects = NULL;		/* named objects */
Object *World;				/* top-level object */


/*
 * Return pointer to named object, NULL if no such object has been defined.
 */
Object *
ObjectGetNamed(name)
char *name;
{
	Object *otmp;
	for (otmp = Objects; otmp; otmp = otmp->next)
		if (strcmp(name, otmp->name) == 0)
			return otmp;
	return (Object *)NULL;
}

/*
 * Add object to list of defined objects.  At this point, the object has
 * been converted to the correct type, and obj->next is either NULL or
 * garbage.
 */
void
ObjectAddToDefined(obj)
Object *obj;
{
	obj->next = Objects;
	Objects = obj;
	if (Options.verbose)
		AggregatePrintInfo(obj, Stats.fstats);
	else
		AggregatePrintInfo(obj, (FILE *)NULL);
}

/*
 * Return a copy of the named object.
 */
Object *
ObjectCopyNamed(name)
char *name;
{
	Object *child;

	child = ObjectGetNamed(name);
	if (child == (Object *)NULL)
		RLerror(RL_PANIC, "There is no object named \"%s\".", name);
	return ObjectCopy(child);
}

void
WorldSetup()
{
	extern ObjList *Defstack;

	/*
	 * Define and setup World object.
	 */
	World = Defstack->obj;	/* World is topmost object on stack */
	if (Defstack->next)
		RLerror(RL_ABORT, "Object def stack is screwey.\n");
	/*
	 * Efficiency hack:  if World list consists of a single
	 * object, with no textures or transformations, can
	 * make World's one child be the World object.
	 */
	World->prims = AggregateConvert(World, World->next);
	ObjectBounds(World);

	/*
	 * Complain if there are no primitives to be rendered.
	 */
	if (World->prims == 0) {
		RLerror(RL_PANIC, "Nothing to be rendered.\n");
	}
}

int
TraceRay(ray, hitlist, mindist, maxdist)
Ray *ray;
HitList *hitlist;
Float mindist, *maxdist;
{
	return intersect(World, ray, hitlist, mindist, maxdist);
}
