⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mytree.cpp

📁 此文档是用vistual studio 2005 开发的用来描述3D-tree 的生长过程
💻 CPP
字号:
#include "stdafx.h"
#include "MyTree.h"
#include <iostream>
#include <cstdlib>
#include <GL/glut.h>
#include "ChGL.h"

MyTree::MyTree() {
	this->maxBranchDepth = 5 + ( rand() % 4 );
	this->maxBranchLength = 0.6f + ( rand() % 6 ) / 10.0f;
	this->baseBranchRadius = 0.1f;
	this->maxBaseLength = maxBranchLength * 3;
	this->leafSize = 0.1f;
	leftBranch = new Branch( maxBranchDepth, maxBranchLength, 60 + rand() % 20, 25  + rand() % 5, baseBranchRadius, 6, "bark.bmp" );
	rightBranch = new Branch( maxBranchDepth, maxBranchLength, 70 + rand() % 20, 15 + rand() % 5, baseBranchRadius, 6, "bark.bmp" );
	leaf = new Leaf( 0.1f, 70.0f, 25.0f, "leaf.bmp" );
	if ( maxBranchLength < 0.7 ) {
		leaf->setVisible( false );
	}
	enviroment = Enviroment();
}

MyTree::MyTree( int maxBranchDepth, float maxBranchLength, float baseBranchRadius, float twist, float expand, int slices, float leafSize ) {
	this->maxBranchDepth = maxBranchDepth;
	this->maxBranchLength = maxBranchLength;
	this->baseBranchRadius = baseBranchRadius;
	this->maxBaseLength = maxBranchLength * 3;
	this->leafSize = leafSize;
	leftBranch = new Branch( maxBranchDepth, maxBranchLength, twist, expand, baseBranchRadius, slices, "bark.bmp" );
	rightBranch = new Branch( maxBranchDepth, maxBranchLength, twist, expand, baseBranchRadius, slices, "bark.bmp" );
	leaf = new Leaf( leafSize, twist, expand, "leaf.bmp" );
	enviroment = Enviroment();
	rebuild();
	pause = false;
}

void MyTree::randomGenerate() {
	this->maxBranchDepth = 5 + ( rand() % 4 );
	this->maxBranchLength = 0.6f + ( rand() % 6 ) / 10.0f;
	this->baseBranchRadius = 0.1f;
	this->maxBaseLength = maxBranchLength * 3;
	this->leafSize = 0.1f;
	leftBranch->setTwist( 60 + rand() % 20 );
	leftBranch->setExpand( 25  + rand() % 5 );
	rightBranch->setTwist( 60 + rand() % 20 );
	rightBranch->setExpand( 25  + rand() % 5 );
	if ( maxBranchLength < 0.7 ) {
		leaf->setVisible( false );
	}
}

void MyTree::rebuild() {
	leaf->setSize( 0.0f );
	this->currentBranchDepth = 0;
	this->currentBaseLength = 0.0f;
	this->currentBranchLength = 0.0f;
	this->currentBranchRadius = 0.0f;
	count = 0;
}

void MyTree::draw() {
	growUp = false;
	drawBase();
	drawBranches( maxBranchDepth, baseBranchRadius, maxBranchLength, 0.0f );
}

void MyTree::showGrowProcess() {
	if ( currentBranchLength < maxBranchLength ) {
		if ( pause == false ) {
			count++;
			if ( count == 10 ) {
				count = 0;
				currentBranchLength += 0.03f;
				float scales = currentBranchLength / maxBranchLength;
				currentBaseLength = maxBaseLength * scales;
				currentBranchDepth = maxBranchDepth * scales;
				currentBranchRadius = baseBranchRadius * scales;
				leaf->setSize( leafSize * scales );
			}
			//if ( currentBranchLength < maxBranchLength / 1.5f  ) {
			//	leaf->setShakeble( false );
			//} else {
			//	leaf->setShakeble( true );
			//}
		}
	}
	else {
		growUp = true;
	}
	enviroment.setAmbient( 0.2f, 0.2f, 0.2f, 1.0f );
	enviroment.setEmission( 0.0f, 0.0f, 0.0f, 1.0f );
	enviroment.resetMaterial();
	glBindTexture( GL_TEXTURE_2D, leftBranch->getTexture() );
	if ( currentBranchRadius < 0.01f ) {
		ChGL::drawCylinder( 0.01, 0.01, currentBaseLength, leftBranch->getSlices() );
	} else {
		ChGL::drawCylinder( currentBranchRadius, currentBranchRadius, currentBaseLength, leftBranch->getSlices() );
	}
	drawBranches( currentBranchDepth, currentBranchRadius, currentBranchLength, 0.0f );
}

void MyTree::drawBase() {
	enviroment.setAmbient( 0.2f, 0.2f, 0.2f, 1.0f );
	enviroment.setEmission( 0.0f, 0.0f, 0.0f, 1.0f );
	enviroment.resetMaterial();
	glBindTexture( GL_TEXTURE_2D, leftBranch->getTexture() );
	ChGL::drawCylinder( baseBranchRadius, baseBranchRadius, maxBaseLength, leftBranch->getSlices() );
}

void MyTree::drawBranches( int stacks, float radius, float length, float twist ) {
	if ( stacks <= 1 && leaf->isVisible() ) {
		enviroment.setAmbient( 0.47f, 0.552f, 0.0f, 1.0f );
		enviroment.setEmission( 0.5f, 0.5f, 0.5f, 1.0f );
		enviroment.resetMaterial();
		leaf->draw();
	}
	if ( stacks > 0 ) {
		glRotatef( leftBranch->getTwist(), 0.0f, 1.0f, 0.0f );
		drawLeftBranch( radius, radius * 0.8f, length, stacks - 1, twist );
		drawRightBranch( radius, radius * 0.8f, length, stacks - 1, twist );

		length *= 0.83f;
		radius *= 0.75f;
		twist += 58.8f;
		drawBranches( stacks - 1, radius, length, twist );
	}
}

void MyTree::drawLeftBranch(  float baseRadius, float topRadius, float length, int depth, int twist ) {
	// draw right branch
	enviroment.setAmbient( 0.2f, 0.2f, 0.2f, 1.0f );
	enviroment.setEmission( 0.0f, 0.0f, 0.0f, 1.0f );
	enviroment.resetMaterial();
	glPushMatrix();
		glRotatef( -leftBranch->getExpand(), 0.0f, 0.0f, 1.0f );
		glRotatef( -twist, 0.0f, 1.0f, 0.0f );
		glBindTexture( GL_TEXTURE_2D, leftBranch->getTexture() );

		ChGL::drawCylinder( baseRadius, topRadius, length, leftBranch->getSlices() );
		drawBranches( depth, topRadius, length * 0.9, twist + leftBranch->getTwist() );
	glPopMatrix();
}

void MyTree::drawRightBranch(  float baseRadius, float topRadius, float length, int depth, int twist ) {
	// draw left branch
	enviroment.setAmbient( 0.2f, 0.2f, 0.2f, 1.0f );
	enviroment.setEmission( 0.0f, 0.0f, 0.0f, 1.0f );
	enviroment.resetMaterial();
	glRotatef( rightBranch->getExpand(), 0.0f, 0.0f, 1.0f );
	glRotatef( twist, 0.0f, 1.0f, 0.0f );
	glBindTexture( GL_TEXTURE_2D, rightBranch->getTexture() );
	glPushMatrix();
		ChGL::drawCylinder( baseRadius, topRadius, length, rightBranch->getSlices() );
	glPopMatrix();
	glTranslatef( 0.0f, length, 0.0f );
}

void MyTree::setMaxBranchDepth( int depth ) {
	this->maxBranchDepth = depth;
}

void MyTree::setMaxBranchLength( float length ) {
	this->maxBranchLength = length;
}

void MyTree::setMaxBaseLength( float length ) {
	this->maxBaseLength = length;
}

void MyTree::setBaseBranchRadius( float radius) {
	this->baseBranchRadius = radius;
}

void MyTree::setBranchSlices( int slices ) {
	leftBranch->setSlices( slices );
	rightBranch->setSlices( slices );
}

void MyTree::setLeafSize( float size ) {
	this->leafSize = size;
	leaf->setSize( size );
}

void MyTree::setLeftBranchTwist( float twist ) {
	leftBranch->setTwist( twist );
	//leaf->setTwist( twist );
}

void MyTree::setLeftBranchExpand( float expand ) {
	leftBranch->setExpand( expand );
	//leaf->setExpand( expand );
}

void MyTree::setRightBranchTwist( float twist ) {
	rightBranch->setTwist( twist );
	//leaf->setTwist( twist );
}

void MyTree::setRightBranchExpand( float expand ) {
	rightBranch->setExpand( expand );
	//leaf->setExpand( expand );
}

void MyTree::setLeafVisible( bool visible ) {
	leaf->setVisible( visible );
}

void MyTree::setLeafShakeble( bool shakeble ) {
	leaf->setShakeble( shakeble );
}

void MyTree::pauseGrow() {
	pause = true;
}

void MyTree::playGrow() {
	pause = false;
}

int MyTree::getMaxBranchDepth() {
	return this->maxBranchDepth;
}

float MyTree::getMaxBranchLangth() {
	return this->maxBranchLength;
}

float MyTree::getMaxBaseLength() {
	return this->maxBaseLength;
}

float MyTree::getBaseBranchRadius() {
	return this->baseBranchRadius;
}

float MyTree::getLeftBranchTwist() {
	return leftBranch->getTwist();
}

float MyTree::getLeftBranchExpand() {
	return leftBranch->getExpand();
}

float MyTree::getRightBranchTwist() {
	return rightBranch->getTwist();
}

float MyTree::getRightBranchExpand() {
	return rightBranch->getExpand();
}

int MyTree::getBranchSlices() {
	return leftBranch->getSlices();
}

float MyTree::getLeafSize() {
	return this->leafSize;
}

bool MyTree::isLeafVisible() {
	return leaf->isVisible();
}

bool MyTree::isLeafShakeble() {
	return leaf->isShakeble();
}

bool MyTree::isGrowUp() {
	return growUp;
}

bool MyTree::isGrowing() {
	return !pause;
}

MyTree::~MyTree() {
	if( leftBranch != NULL ) {
		delete leftBranch;
		leftBranch = NULL;
	}
	if( rightBranch ) {
		delete rightBranch;
		rightBranch = NULL;
	}
	if ( leaf ) {
		delete leaf;
		leaf = NULL;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -