#ifndef MXBLOCKMODEL_INCLUDED // -*- C++ -*- #define MXBLOCKMODEL_INCLUDED #if !defined(__GNUC__) # pragma once #endif /************************************************************************ MxBlockModel Copyright (C) 1998 Michael Garland. See "COPYING.txt" for details. $Id: MxBlockModel.h,v 1.22 1999/01/22 17:28:16 garland Exp $ ************************************************************************/ #include "MxDynBlock.h" #include "MxGeoPrims.h" #include "MxRaster.h" #define MX_UNBOUND 0x0 #define MX_PERFACE 0x1 #define MX_PERVERTEX 0x2 #define MX_MAX_BINDING 0x2 #define MX_NORMAL_MASK 0x3 #define MX_COLOR_MASK (0x3<<2) #define MX_TEXTURE_MASK (0x3<<4) #define MX_ALL_MASK (MX_NORMAL_MASK|MX_COLOR_MASK|MX_TEXTURE_MASK) class MxBlockModel { private: unsigned char cbinding, nbinding, tbinding; unsigned int flags; // Required blocks MxDynBlock vertices; MxDynBlock faces; // Optional blocks MxDynBlock *normals; MxDynBlock *colors; MxDynBlock *tcoords; // prop_block *properties; // Indirect block for arbitrary properties // Optional texture map MxRaster *tex; char *tex_name; protected: virtual MxVertexID alloc_vertex(float, float, float); virtual void init_vertex(MxVertexID) { } virtual void free_vertex(MxVertexID) { } virtual MxFaceID alloc_face(MxVertexID, MxVertexID, MxVertexID); virtual void init_face(MxFaceID) { } virtual void free_face(MxFaceID) { } public: uint binding_mask; public: MxBlockModel(int nvert, int nface) : vertices(nvert), faces(nface) { colors = NULL; normals = NULL; tcoords = NULL; cbinding = nbinding = tbinding = MX_UNBOUND; binding_mask = MX_ALL_MASK; tex = NULL; tex_name = NULL; } virtual ~MxBlockModel() { if( normals ) delete normals; if( colors ) delete colors; if( tcoords ) delete tcoords; if( tex ) delete tex; if( tex_name ) delete tex_name; } unsigned int vert_count() const { return vertices.length(); } unsigned int face_count() const { return faces.length(); } unsigned int color_count() const { return (colors?colors->length():0); } unsigned int normal_count() const { return (normals?normals->length():0); } uint texcoord_count() const { return (tcoords?tcoords->length():0); } MxVertexID add_vertex(float, float, float); MxFaceID add_face(uint, uint, uint, bool will_link=true); unsigned int add_color(float, float, float); unsigned int add_normal(float, float, float); unsigned int add_texcoord(float, float); MxVertexID add_vertex(float *v) { return add_vertex(v[0], v[1], v[2]); } MxFaceID add_face(unsigned int *f) { return add_face(f[0], f[1], f[2]); } void remove_vertex(MxVertexID v); void remove_face(MxFaceID f); MxVertex& vertex(unsigned int i) { return vertices(i); } MxFace& face(unsigned int i) { return faces(i); } MxVertex& corner(MxFaceID f, short i) { return vertex(face(f)[i]); } MxColor& color(unsigned int i) { assert(colors); return (*colors)(i); } MxNormal& normal(unsigned int i) { assert(normals); return (*normals)(i); } MxTexCoord& texcoord(uint i) { assert(tcoords); return (*tcoords)(i); } int color_binding() { return (cbinding&(binding_mask>>2)); } int normal_binding() { return (nbinding&binding_mask); } int texcoord_binding() { return (tbinding&(binding_mask>>4)); } void color_binding(unsigned char b); void normal_binding(unsigned char b); void texcoord_binding(unsigned char b); const char *binding_name(int); int parse_binding(const char *); MxRaster *texmap() const { return tex; } const char *texmap_name() const { return tex_name; } uint add_texmap(MxRaster *, const char *name); void compute_face_normal(MxFaceID, double *, bool will_unitize=true); void compute_face_normal(MxFaceID, float *, bool will_unitize=true); double compute_face_area(MxFaceID); double compute_face_perimeter(MxFaceID, bool *edge_flags=NULL); double compute_corner_angle(MxFaceID, uint); }; // MXBLOCKMODEL_INCLUDED #endif