This repository has been archived on 2024-12-16. You can view files and clone it, but cannot push or open issues or pull requests.
CodeBlocksPortable/WATCOM/samples/ide/box.cpp

218 lines
6.5 KiB
C++

/****************************************************************************
*
* 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 );
}
}