/**************************************************************************** * * Open Watcom Project * * Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved. * * ======================================================================== * * This file contains Original Code and/or Modifications of Original * Code as defined in and that are subject to the Sybase Open Watcom * Public License version 1.0 (the 'License'). You may not use this file * except in compliance with the License. BY USING THIS FILE YOU AGREE TO * ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is * provided with the Original Code and Modifications, and is also * available at www.sybase.com/developer/opensource. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR * NON-INFRINGEMENT. Please see the License for the specific language * governing rights and limitations under the License. * * ======================================================================== * * Description: Low level classes for 3D demo. * ****************************************************************************/ #include "box.hpp" static float point::world_scale = 12 * 12; // ie 12 feet static float point::vertical_shift = 0; // Functions which could be inlined point::point( float x0, float y0, float z0 ) : x(x0), y(y0), z(z0) { } point::point( point& src ) : x(src.x), y(src.y), z(src.z) { } void point::move_left( float amount ) { x -= amount; } void point::move_right( float amount ) { x += amount; } void point::move_up( float amount ) { y += amount; } void point::move_down( float amount ) { y -= amount; } void point::move_forward( float amount ) { z -= amount; } void point::move_back( float amount ) { z += amount; } color::color(unsigned char red,unsigned char green,unsigned char blue) : r(red), g(green), b(blue) { } color::color(const color& src) : r(src.r), g(src.g), b(src.b) { } color::color() : r(0), g(0), b(0) { } void color::rgb(unsigned char red, unsigned char green, unsigned char blue) { r = red; g = green; b = blue; } void color::rgb(color& src) { rgb( src.r, src.g, src.b); } void color::rgb(color* src) { rgb( src->r, src->g, src->b); } void color::red( unsigned char intensity ) { r = intensity; } void color::green( unsigned char intensity ) { g = intensity; } void color::blue( unsigned char intensity ) { b = intensity; } float box::width() { return size_vector.x; } float box::height() { return size_vector.y; } float box::depth() { return size_vector.z; } void box::left( float x0 ) { x = x0; } void box::right( float x0 ) { x = x0 - size_vector.x; } void box::front( float z0 ) { z = z0 - size_vector.z; } void box::back( float z0 ) { z = z0; } void box::top( float y0 ) { y = y0 - size_vector.y; } void box::bottom( float y0 ) { y = y0; } float box::left() { return x; } float box::right() { return x + size_vector.x; } float box::top() { return y + size_vector.y; } float box::bottom() { return y; } float box::front() { return( z + size_vector.z ); } float box::back() { return z; } float box::mid_width() { return x + size_vector.x / 2; } float box::mid_height() { return y + size_vector.y / 2; } float box::mid_depth() { return z + size_vector.z / 2; } void point::rotate( orientation move ) { float temp; switch( move % 4 ) { case FRONT: // nothing to do break; case RIGHT: temp = x; x = z; z = -temp; break; case BACK: x = -x; z = -z; break; case LEFT: temp = x; x = -z; z = temp; break; } } void point::moveto( float x0, float y0, float z0 ) { x = x0; y = y0; z = z0; } void point::moveto( point& origin ) { x = origin.x; y = origin.y; z = origin.z; } void point::shift( float xdelta, float ydelta, float zdelta ) { x += xdelta; y += ydelta; z += zdelta; } void point::shift( point& vector ) { shift( vector.x, vector.y, vector.z ); } box::box( float across, float depth, float height ) : point(0,0,0), size_vector(across, height, depth), facing(FRONT) { children = 0; sibling = 0; } box::~box() { delete children; delete sibling; } static void point::world_size( float wide, float deep, float high ) { // To keep proportions correct, just remember the largest of the dimensions world_scale = wide; if( world_scale < deep ) { world_scale = deep; } if( world_scale < high ) { world_scale = high; vertical_shift = 0; } else { vertical_shift = (world_scale - high) / 2; } } void box::add(box* child) { child->sibling = children; children = child; } void box::orient( orientation rotation ) { facing = (orientation) ((facing + rotation) % 4); } void box::orient( box * other ) { orient( other->facing ); } void box::position_to_right_of( box& to_left ) { // Move to same position & facing as to_left moveto( to_left ); orient( to_left.facing ); // Now move across by the width of to_left point shift_vector( to_left.width(), 0, 0 ); shift_vector.rotate( facing ); shift( shift_vector ); } void box::change_color( color newclr ) { rgb( newclr ); for( box * curr = children; curr; curr = curr->sibling ) { curr->change_color( newclr ); } } void box::draw( point& origin, orientation face ) { // First, combine the rotations face = (orientation) ((face + facing) % 4); if( children ) { for( box * curr = children; curr; curr = curr->sibling ) { point curr_origin = *curr; curr_origin.rotate( face ); curr_origin.shift( origin ); curr->draw( curr_origin, face ); } } else { // Only draw outer box if there is no children point new_size = size_vector; new_size.rotate( face ); point other_corner = origin; other_corner.shift( new_size ); draw_box( origin.x / world_scale, other_corner.x / world_scale, (origin.y + vertical_shift) / world_scale, (other_corner.y + vertical_shift) / world_scale, origin.z / world_scale, other_corner.z / world_scale, r, g, b ); } }