[BACK]Return to pfsponge.c CVS log [TXT][DIR] Up to [Development] / performer / src / lib / libpfdb / libpfsponge

File: [Development] / performer / src / lib / libpfdb / libpfsponge / pfsponge.c (download)

Revision 1.1, Tue Nov 21 21:39:35 2000 UTC (16 years, 11 months ago) by flynnt
Branch: MAIN
CVS Tags: HEAD

Initial check-in based on OpenGL Performer 2.4 tree.
-flynnt

/*
 * Copyright 1993, 1995, Silicon Graphics, Inc.
 * ALL RIGHTS RESERVED
 *
 * This source code ("Source Code") was originally derived from a
 * code base owned by Silicon Graphics, Inc. ("SGI")
 * 
 * LICENSE: SGI grants the user ("Licensee") permission to reproduce,
 * distribute, and create derivative works from this Source Code,
 * provided that: (1) the user reproduces this entire notice within
 * both source and binary format redistributions and any accompanying
 * materials such as documentation in printed or electronic format;
 * (2) the Source Code is not to be used, or ported or modified for
 * use, except in conjunction with OpenGL Performer; and (3) the
 * names of Silicon Graphics, Inc.  and SGI may not be used in any
 * advertising or publicity relating to the Source Code without the
 * prior written permission of SGI.  No further license or permission
 * may be inferred or deemed or construed to exist with regard to the
 * Source Code or the code base of which it forms a part. All rights
 * not expressly granted are reserved.
 * 
 * This Source Code is provided to Licensee AS IS, without any
 * warranty of any kind, either express, implied, or statutory,
 * including, but not limited to, any warranty that the Source Code
 * will conform to specifications, any implied warranties of
 * merchantability, fitness for a particular purpose, and freedom
 * from infringement, and any warranty that the documentation will
 * conform to the program, or any warranty that the Source Code will
 * be error free.
 * 
 * IN NO EVENT WILL SGI BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT
 * LIMITED TO DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES,
 * ARISING OUT OF, RESULTING FROM, OR IN ANY WAY CONNECTED WITH THE
 * SOURCE CODE, WHETHER OR NOT BASED UPON WARRANTY, CONTRACT, TORT OR
 * OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
 * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM,
 * OR AROSE OUT OF USE OR RESULTS FROM USE OF, OR LACK OF ABILITY TO
 * USE, THE SOURCE CODE.
 * 
 * Contact information:  Silicon Graphics, Inc., 
 * 1600 Amphitheatre Pkwy, Mountain View, CA  94043, 
 * or:  http://www.sgi.com
 */

/*
 * pfsponge.c: $Revision: 1.1 $ $Date: 2000/11/21 21:39:35 $
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

#include <Performer/pf.h>
#include <Performer/pfdu.h>

#define	EAST	0x01
#define	WEST	0x02
#define	NORTH	0x04
#define	SOUTH	0x08
#define	TOP	0x10
#define	BOTTOM	0x20

#define	ALL	(EAST|WEST|NORTH|SOUTH|TOP|BOTTOM)

#define	XMIN	(-256.0f)
#define	XMAX	( 256.0f)
#define	YMIN	(-256.0f)
#define	YMAX	( 256.0f)
#define	ZMIN	(-256.0f)
#define	ZMAX	( 256.0f)

#define	RMIN	0.1f
#define	RMAX	0.7f
#define	GMIN	0.1f
#define	GMAX	0.7f
#define	BMIN	0.1f
#define	BMAX	0.7f

static int first = 0;
static pfGroup *group = NULL;

static void
spongeQuad (
    pfdGeom *buffer,
    pfVec3 a, pfVec3 b, pfVec3 c, pfVec3 d)
{
    int v;
    int t;

    buffer->numVerts = 4; 
    buffer->primtype = PFGS_POLYS;
    for (t = 0 ; t < PF_MAX_TEXTURES ; t ++)
	buffer->tbind[t] = PFGS_OFF;
    buffer->nbind = PFGS_OFF;
    buffer->cbind = PFGS_PER_VERTEX;

    pfCopyVec3(buffer->coords[0], a);
    pfCopyVec3(buffer->coords[1], b);
    pfCopyVec3(buffer->coords[2], c);
    pfCopyVec3(buffer->coords[3], d);

    for (v = 0; v < 4; v++)
	pfSetVec4(buffer->colors[v],
	    RMIN + (RMAX-RMIN)*(buffer->coords[v][0]-XMIN)/(XMAX-XMIN),
	    GMIN + (GMAX-GMIN)*(buffer->coords[v][1]-YMIN)/(YMAX-YMIN),
	    BMIN + (BMAX-BMIN)*(buffer->coords[v][2]-ZMIN)/(ZMAX-ZMIN),
	    1.0);

    pfdAddBldrGeom(buffer, 1);
}

static int
sponge (
    pfdGeom *buffer,
    int levels, 
    int sides, 
    float xMin, float xMax, 
    float yMin, float yMax, 
    float zMin, float zMax)
{
    long	polygons = 0;
    pfVec3	a, b, c, d;
    
    if (sides == 0)
        return 0;
    
    if (levels < 1)
    {
        if (sides & NORTH)
	{
	    pfSetVec3(a, xMax, yMax, zMin);
	    pfSetVec3(b, xMin, yMax, zMin);
	    pfSetVec3(c, xMin, yMax, zMax);
	    pfSetVec3(d, xMax, yMax, zMax);
	    spongeQuad(buffer, a, b, c, d);
	    polygons += 2;
    	}
        if (sides & SOUTH)
	{
	    pfSetVec3(a, xMin, yMin, zMin);
	    pfSetVec3(b, xMax, yMin, zMin);
	    pfSetVec3(c, xMax, yMin, zMax);
	    pfSetVec3(d, xMin, yMin, zMax);
	    spongeQuad(buffer, a, b, c, d);
	    polygons += 2;
    	}
        if (sides & EAST)
	{
	    pfSetVec3(a, xMax, yMin, zMin);
	    pfSetVec3(b, xMax, yMax, zMin);
	    pfSetVec3(c, xMax, yMax, zMax);
	    pfSetVec3(d, xMax, yMin, zMax);
	    spongeQuad(buffer, a, b, c, d);
	    polygons += 2;
    	}
        if (sides & WEST)
	{
	    pfSetVec3(a, xMin, yMax, zMin);
	    pfSetVec3(b, xMin, yMin, zMin);
	    pfSetVec3(c, xMin, yMin, zMax);
	    pfSetVec3(d, xMin, yMax, zMax);
	    spongeQuad(buffer, a, b, c, d);
	    polygons += 2;
    	}
        if (sides & TOP)
	{
	    pfSetVec3(a, xMin, yMin, zMax);
	    pfSetVec3(b, xMax, yMin, zMax);
	    pfSetVec3(c, xMax, yMax, zMax);
	    pfSetVec3(d, xMin, yMax, zMax);
	    spongeQuad(buffer, a, b, c, d);
	    polygons += 2;
    	}
        if (sides & BOTTOM)
	{
	    pfSetVec3(a, xMin, yMax, zMin);
	    pfSetVec3(b, xMax, yMax, zMin);
	    pfSetVec3(c, xMax, yMin, zMin);
	    pfSetVec3(d, xMin, yMin, zMin);
	    spongeQuad(buffer, a, b, c, d);
	    polygons += 2;
    	}
    }
    else
    {
        float	xThird = (xMax - xMin)/3.0;
        float	xLess  =  xMin + xThird;
        float	xMore  =  xMax - xThird;
    
        float	yThird = (yMax - yMin)/3.0;
        float	yLess  =  yMin + yThird;
        float	yMore  =  yMax - yThird;
    
        float	zThird = (zMax - zMin)/3.0;
        float	zLess  =  zMin + zThird;
        float	zMore  =  zMax - zThird;
    
        --levels;
        
        /* 
         * 6 7 8
         * 4   5	Top layer (eight sub-squares)
         * 1 2 3
         */
        polygons += sponge(buffer, levels,  sides & (SOUTH|WEST|TOP), 
            xMin,  xLess, yMin, yLess, zMore, zMax);
	if (levels == first) pfAddChild(group, pfdBuild());
        polygons += sponge(buffer, levels, (sides & (SOUTH|TOP))|NORTH|BOTTOM, 
            xLess, xMore, yMin, yLess, zMore, zMax);
	if (levels == first) pfAddChild(group, pfdBuild());
        polygons += sponge(buffer, levels,  sides & (SOUTH|EAST|TOP), 
            xMore, xMax,  yMin, yLess, zMore, zMax);
	if (levels == first) pfAddChild(group, pfdBuild());
        
        polygons += sponge(buffer, levels, (sides & (WEST|TOP))|EAST|BOTTOM, 
            xMin,  xLess, yLess, yMore, zMore, zMax);
	if (levels == first) pfAddChild(group, pfdBuild());
        polygons += sponge(buffer, levels, (sides & (EAST|TOP))|WEST|BOTTOM, 
            xMore, xMax,  yLess, yMore, zMore, zMax);
	if (levels == first) pfAddChild(group, pfdBuild());
        
        polygons += sponge(buffer, levels,  sides & (NORTH|WEST|TOP), 
            xMin,  xLess, yMore, yMax, zMore, zMax);
	if (levels == first) pfAddChild(group, pfdBuild());
        polygons += sponge(buffer, levels, (sides & (NORTH|TOP))|SOUTH|BOTTOM, 
            xLess, xMore, yMore, yMax, zMore, zMax);
	if (levels == first) pfAddChild(group, pfdBuild());
        polygons += sponge(buffer, levels,  sides & (NORTH|EAST|TOP), 
            xMore, xMax,  yMore, yMax, zMore, zMax);
	if (levels == first) pfAddChild(group, pfdBuild());
    	
        /* 
         * 3   4
         *      	Middle layer (four sub-squares)
         * 1   2
         */
        polygons += sponge(buffer, levels, (sides & (SOUTH|WEST))|NORTH|EAST, 
            xMin,  xLess, yMin, yLess, zLess, zMore);
	if (levels == first) pfAddChild(group, pfdBuild());
        polygons += sponge(buffer, levels, (sides & (SOUTH|EAST))|NORTH|WEST, 
            xMore, xMax,  yMin, yLess, zLess, zMore);
	if (levels == first) pfAddChild(group, pfdBuild());
        
        polygons += sponge(buffer, levels, (sides & (NORTH|WEST))|SOUTH|EAST, 
            xMin,  xLess, yMore, yMax, zLess, zMore);
	if (levels == first) pfAddChild(group, pfdBuild());
        polygons += sponge(buffer, levels, (sides & (NORTH|EAST))|SOUTH|WEST, 
            xMore, xMax,  yMore, yMax, zLess, zMore);
	if (levels == first) pfAddChild(group, pfdBuild());
        
        /* 
         * 6 7 8
         * 4   5	Bottom layer (eight sub-squares)
         * 1 2 3
         */
        polygons += sponge(buffer, levels,  sides & (SOUTH|WEST|BOTTOM), 
            xMin,  xLess, yMin, yLess, zMin, zLess);
	if (levels == first) pfAddChild(group, pfdBuild());
        polygons += sponge(buffer, levels, (sides & (SOUTH|BOTTOM))|NORTH|TOP, 
            xLess, xMore, yMin, yLess, zMin, zLess);
	if (levels == first) pfAddChild(group, pfdBuild());
        polygons += sponge(buffer, levels,  sides & (SOUTH|EAST|BOTTOM), 
            xMore, xMax,  yMin, yLess, zMin, zLess);
	if (levels == first) pfAddChild(group, pfdBuild());
        
        polygons += sponge(buffer, levels, (sides & (WEST|BOTTOM))|EAST|TOP, 
            xMin,  xLess, yLess, yMore, zMin, zLess);
	if (levels == first) pfAddChild(group, pfdBuild());
        polygons += sponge(buffer, levels, (sides & (EAST|BOTTOM))|WEST|TOP, 
            xMore, xMax,  yLess, yMore, zMin, zLess);
	if (levels == first) pfAddChild(group, pfdBuild());
        
        polygons += sponge(buffer, levels,  sides & (NORTH|WEST|BOTTOM), 
            xMin,  xLess, yMore, yMax, zMin, zLess);
	if (levels == first) pfAddChild(group, pfdBuild());
        polygons += sponge(buffer, levels, (sides & (NORTH|BOTTOM))|SOUTH|TOP, 
            xLess, xMore, yMore, yMax, zMin, zLess);
	if (levels == first) pfAddChild(group, pfdBuild());
        polygons += sponge(buffer, levels,  sides & (NORTH|EAST|BOTTOM), 
            xMore, xMax,  yMore, yMax, zMin, zLess);
	if (levels == first) pfAddChild(group, pfdBuild());
    }
    
    return polygons;
}

/*
 * pfdLoadFile_sponge -- build a Sponge for IRIS Performer
 */
extern pfNode *
pfdLoadFile_sponge (char *fileName)
{
    pfdGeom	*buffer		= NULL;
    pfNode	*node		= NULL;
    pfMaterial	*material	= NULL;
    int		 i		= 0;
    int		 levels		= 0;
    int	 	 numTris	= 0;
    double	 startTime	= pfGetTime();
    double	 elapsedTime	= 0.0;

    /* restore builder to initial state */
    pfdResetBldrGeometry();
    pfdResetBldrState();

    /* extract recursive depth from "file name" */
    if (sscanf(fileName, "%d", &levels) != 1)
	return NULL;

    /* initialize utility library triangle/geoset builder */
    buffer = pfdNewGeom(4);

    /* enable lighting for sponge object */
    pfdBldrStateMode(PFSTATE_ENLIGHTING, PF_ON);

    /* specify a material for the sponge */
    material = (pfMaterial*)pfdGetTemplateObject(pfGetMtlClassType());
    pfMtlColor(material, PFMTL_AMBIENT,  0.2f, 0.2f, 0.2f);
    pfMtlColor(material, PFMTL_DIFFUSE,  0.8f, 0.8f, 0.8f);
    pfMtlColor(material, PFMTL_SPECULAR, 0.4f, 0.4f, 0.4f);
    pfMtlShininess(material, 8.0f);
    pfMtlColorMode(material, PFMTL_FRONT, PFMTL_CMODE_AD);
    pfdBldrStateAttr(PFSTATE_FRONTMTL, material);
    pfdBldrStateMode(PFSTATE_ENLIGHTING, PF_ON);
    pfdBldrStateMode(PFSTATE_CULLFACE, PFCF_BACK);

    /* add geometry to builder */
    first = levels - 1;
    group = pfNewGroup();
    numTris += sponge(buffer, levels, ALL, 
	XMIN, XMAX, YMIN, YMAX, ZMIN, ZMAX);

    /* get a complete scene graph representing file's primitives */
#if 0
    node = pfdBuild();
#else
    node = (pfNode *)group;
#endif
    if (node != NULL)
	pfNodeName(node, fileName);

    /* delete allocations */
    pfdDelGeom(buffer);

    /* print statistics */
    pfNotify(PFNFY_NOTICE, PFNFY_PRINT, "pfdLoadFile_sponge: %s", fileName);
    pfNotify(PFNFY_INFO,   PFNFY_MORE,  "  Input Data:");
    pfNotify(PFNFY_INFO,   PFNFY_MORE,  "    Recursive levels:   %8ld", levels);
    pfNotify(PFNFY_INFO,   PFNFY_MORE,  "    Triangles:          %8ld", numTris);

    return node;
}