예제 #1
0
const mydefs::Triangle3d TriangleIterator::operator*()
{
////////////////////////////////////////////////////////////////////////////////
int plus1mod3[3] = {1, 2, 0};
int minus1mod3[3] = {2, 0, 1};

#define org(otri, vertexptr)                                                  \
  vertexptr = (vertex) (otri).tri[plus1mod3[(otri).orient] + 3]

#define dest(otri, vertexptr)                                                 \
  vertexptr = (vertex) (otri).tri[minus1mod3[(otri).orient] + 3]

#define apex(otri, vertexptr)                                                 \
  vertexptr = (vertex) (otri).tri[(otri).orient + 3]
////////////////////////////////////////////////////////////////////////////////
	mydefs::Triangle3d triangle;
	TVertex v1;
	TVertex v2;
	TVertex v3;
	
	if( validTriangle() )
	{
		org(mCurrentTriangle, v1);
		dest(mCurrentTriangle, v2);
		apex(mCurrentTriangle, v3);
		triangle = wykobi::make_triangle( v1[0], v1[1], v1[2], 
			v2[0], v2[1], v2[2],
			v3[0], v3[1], v3[2]);
	}
	
	return triangle;
}
예제 #2
0
파일: tin.cpp 프로젝트: cugwhp/terrace
bool TIN::findTriangle(double theX, double theY, mydefs::Triangle3d& theTriangle3d) const
{

////////////////////////////////////////////////////////////////////////////////
int plus1mod3[3] = {1, 2, 0};
int minus1mod3[3] = {2, 0, 1};

#define org(otri, vertexptr)                                                  \
  vertexptr = (vertex) (otri).tri[plus1mod3[(otri).orient] + 3]

#define dest(otri, vertexptr)                                                 \
  vertexptr = (vertex) (otri).tri[minus1mod3[(otri).orient] + 3]

#define apex(otri, vertexptr)                                                 \
  vertexptr = (vertex) (otri).tri[(otri).orient + 3]
////////////////////////////////////////////////////////////////////////////////

	bool result = false;

	TVertex v;
	TVertex t1;
	TVertex t2;
	TVertex t3;

	v = static_cast<TVertex>(new double[2]);
	v[0] = theX;
	v[1] = theY;

	if(preciselocate(mMesh, mBehavior, v, mRecentTri, 0) != OUTSIDE) 
	{
		org(*mRecentTri, t1);
		dest(*mRecentTri, t2);
		apex(*mRecentTri, t3);
		theTriangle3d = wykobi::make_triangle(t1[0], t1[1], t1[2],
			t2[0], t2[1], t2[2],
			t3[0], t3[1], t3[2]);
		result = true;
	} 

	delete [] v;

	return result;
}
예제 #3
0
// Funnel algorithm
void NavMap::funnel(Vector &start, Vector &end) {
	unTriangulatePath();

	funnelVector.swap(std::vector<Vector>());
	funnelVector.push_back(start);
	if(!intersectBounds(start, end)) {
		funnelVector.push_back(end);
		return;
	}
	
	portals.emplace(portals.begin(), start);
	portals.emplace(portals.begin(), start);
	portals.push_back(end);
	portals.push_back(end);

	Vector apex(start);
	Vector left(start);
	Vector right(start);

	int apexI = 0;
	int leftI = 0;
	int rightI = 0;

	Vector R;
	Vector L;

	for(unsigned int i = 2, j = 0; i < portals.size() && j < 1000; i+=2, j+=2){
		if(!intersectBounds(apex, end)) {
			funnelVector.push_back(end);
			return;
		}

		Vector &pi1 = portals[i + 1];
		Vector &pi = portals[i];

		R = pi1 + (pi - pi1) * 0.99;
		L = pi + (pi1 - pi) * 0.99;

		if(triarea2(apex, right, R) <= 0.f) {
			if(Vector::equal(apex, right, 0.01f) || triarea2(apex, left, R) >= 0.f) {
				right = R;
				rightI = i;
			} else {
				funnelVector.push_back(left);
				apex = left;
				apexI = leftI;

				right = apex;
				rightI = apexI;

				i = apexI;
				break;
			}
		}

		if(triarea2(apex, left, L) >= 0.f) {
			if(Vector::equal(apex, left, 0.01f) || triarea2(apex, right, L) <= 0.f) {
				left = L;
				leftI = i;
			} else {
				funnelVector.push_back(right);
				apex = right;
				apexI = rightI;

				left = apex;
				leftI = apexI;

				i = apexI;
				break;
			}
		}
	}
}
예제 #4
0
    // This customized version carves holes defined by the regions.
    // It'll remove any element which doesn't receive any region.
    int custom_carveholes(struct mesh *m, struct behavior *b, const int *outside, const int *inside)
    {
        struct otri neighbortri;
        struct otri triangleloop;
        struct osub subsegloop;
        triangle **temptri;
        triangle ptr;                     /* Temporary variable used by sym(). */
        double area;
        double attribute;
        double triangle_attribute;
        int sane_mesh;

        poolinit(& m->viri, sizeof( triangle * ), VIRUSPERBLOCK, VIRUSPERBLOCK, 0);

        /* Assigns every triangle a regional attribute of -1 */
        traversalinit(& m->triangles);
        triangleloop.orient = 0;
        triangleloop.tri = triangletraverse(m);
        while ( triangleloop.tri != ( triangle * ) NULL ) {
            setelemattribute(triangleloop, m->eextras, -1.0);
            triangleloop.tri = triangletraverse(m);
        }

        sane_mesh = 1;

        /* Loop over all segments */
        traversalinit(& m->subsegs);
        subsegloop.ss = subsegtraverse(m);
        subsegloop.ssorient = 0;
        while ( subsegloop.ss != ( subseg * ) NULL ) {
            if ( subsegloop.ss != m->dummysub ) {
                /* First neighbor. */
                ssymself(subsegloop);
                stpivot(subsegloop, neighbortri);
                if ( neighbortri.tri != m->dummytri ) {
                    area = 0.0; /// @todo Possible set this as the minimum as well.
                    attribute = outside [ mark(subsegloop) - 1 ];
                    triangle_attribute = elemattribute(neighbortri, m->eextras);

                    /* The region no number yet. */
                    if ( triangle_attribute < 0 && attribute >= 0 ) {
                        infect(neighbortri);
                        temptri = ( triangle ** ) poolalloc(& m->viri);
                        * temptri = neighbortri.tri;
                        /* Apply one region's attribute and/or area constraint. */
                        regionplague(m, b, attribute, area);
                        /* The virus pool should be empty now. */
                    } else if ( attribute >= 0 && triangle_attribute >= 0 && attribute != triangle_attribute ) {
                        /* Check for problems. */
                        vertex v1, v2, v3;
                        org(neighbortri, v1);
                        dest(neighbortri, v2);
                        apex(neighbortri, v3);
                        fprintf(stdout, "Error: inconsistent region information (new %d, old %d from %d) (outside) at (%e, %e)\n",
                                ( int ) attribute, ( int ) triangle_attribute, ( int ) mark(subsegloop), ( v1 [ 0 ] + v2 [ 0 ] + v3 [ 0 ] ) / 3, ( v1 [ 1 ] + v2 [ 1 ] + v3 [ 1 ] ) / 3);
                        sane_mesh = 0;
                    }
                }

                /* Second neighbor (same procedure). */
                ssymself(subsegloop);
                stpivot(subsegloop, neighbortri);
                if ( neighbortri.tri != m->dummytri ) {
                    area = 0.0;
                    attribute = inside [ mark(subsegloop) - 1 ];
                    triangle_attribute = elemattribute(neighbortri, m->eextras);

                    if ( triangle_attribute < 0 && attribute >= 0 ) {
                        infect(neighbortri);
                        temptri = ( triangle ** ) poolalloc(& m->viri);
                        * temptri = neighbortri.tri;
                        regionplague(m, b, attribute, area);
                    } else if ( attribute >= 0 && triangle_attribute >= 0 && attribute != triangle_attribute ) {
                        vertex v1, v2, v3;
                        org(neighbortri, v1);
                        dest(neighbortri, v2);
                        apex(neighbortri, v3);
                        fprintf(stdout, "Error: inconsistent region information (new %d, old %d from %d) (inside) at (%e, %e)\n",
                                ( int ) attribute, ( int ) triangle_attribute, ( int ) mark(subsegloop), ( v1 [ 0 ] + v2 [ 0 ] + v3 [ 0 ] ) / 3, ( v1 [ 1 ] + v2 [ 1 ] + v3 [ 1 ] ) / 3);
                        sane_mesh = 0;
                    }
                }

                subsegloop.ss = subsegtraverse(m);
            }
        }

        /* Remove all triangles with marker 0.0 */
        traversalinit(& m->triangles);
        triangleloop.tri = triangletraverse(m);
        int triangle_number = 0;
        while ( triangleloop.tri != ( triangle * ) NULL ) {
            if ( triangleloop.tri != m->dummytri ) {
                triangle_number++;
                attribute = elemattribute(triangleloop, m->eextras);
                if ( attribute == -1.0 ) {
                    fprintf(stderr, "Broken mesh at triangle %d\n", triangle_number);
                    sane_mesh = 0;
                } else if ( attribute == 0.0 ) {
                    infect(triangleloop);
                    temptri = ( triangle ** ) poolalloc(& m->viri);
                    * temptri = triangleloop.tri;
                }
            }
            triangleloop.tri = triangletraverse(m);
        }
        /* Remove the marked elements */
        plague(m, b);

        if ( b->regionattrib && !b->refine ) {
            /* Note the fact that each triangle has an additional attribute. */
            m->eextras++;
        }

        /* Free up memory. */
        pooldeinit(& m->viri);

        return sane_mesh;
    }
예제 #5
0
파일: Funnel.cpp 프로젝트: argenos/Menge
	void FunnelPlanner::computeCrossing( float radius, const Vector2 & startPos, PortalPath * path, size_t startPortal ) {
		assert( path->getPortalCount() > 0 && "Funnel planner should only be applied to PortalPaths with at least one portal" );
		FunnelApex apex( startPortal - 1, startPos );	// if startPortal is zero, this should go to all 1s...i.e. -1 > all other size_t values
		
		const WayPortal * portal = path->getPortal( startPortal );
		Vector2 pLeft( portal->getLeft( radius ) );
		Vector2 pRight( portal->getRight( radius ) );
		Vector2 dirLeft( pLeft - apex._pos );
		Vector2 dirRight( pRight - apex._pos );
	#ifdef SIMPLE_FUNNEL
		FunnelEdge funnelLeft( startPortal, dirLeft );
		FunnelEdge funnelRight( startPortal, dirRight );
		size_t currPortal = startPortal + 1;
		const size_t PORTAL_COUNT = path->getPortalCount();
		while ( currPortal < PORTAL_COUNT ) {
			portal = path->getPortal( currPortal );
			pLeft.set( portal->getLeft( radius ) );
			pRight.set( portal->getRight( radius ) );
			dirLeft.set( pLeft - apex._pos );
			dirRight.set( pRight - apex._pos );

			// test left side of the funnel
			if ( funnelRight.isOnRight( dirLeft ) ) {
				// the portal's funnel is on the right of the current funnel
				Vector2 oldApex = apex._pos;
				Vector2 newApex = funnelRight._dir + apex._pos;
				//if ( apex._id != -1 && apex._id < currPortal ) {
					path->setWaypoints( apex._id + 1, funnelRight._id + 1, newApex, norm( funnelRight._dir ) );
				//}
				apex.set( funnelRight._id, newApex );
				currPortal = funnelRight._id + 1;

				portal = path->getPortal( currPortal );
				pLeft.set( portal->getLeft( radius ) );
				pRight.set( portal->getRight( radius ) );
				dirLeft.set( pLeft - apex._pos );
				dirRight.set( pRight - apex._pos );
				funnelLeft.set( currPortal, dirLeft );
				funnelRight.set( currPortal, dirRight );
				++currPortal;
				
				continue;
			} else if ( funnelLeft.isOnRight( dirLeft ) ) {
				funnelLeft.set( currPortal, dirLeft );
			}

			// test right side of the funnel
			if ( funnelLeft.isOnLeft( dirRight ) ) {
				// the portal's funnel is on the left of the current funnel
				Vector2 oldApex = apex._pos;
				Vector2 newApex = funnelLeft._dir + apex._pos;
				//if ( apex._id != -1 && apex._id < currPortal ) {
					path->setWaypoints( apex._id + 1, funnelLeft._id + 1, newApex, norm( funnelLeft._dir ) );
				//}
				apex.set( funnelLeft._id, newApex );
				currPortal = funnelLeft._id + 1;

				portal = path->getPortal( currPortal );
				pLeft.set( portal->getLeft( radius ) );
				pRight.set( portal->getRight( radius ) );
				dirLeft.set( pLeft - apex._pos );
				dirRight.set( pRight - apex._pos );
				funnelLeft.set( currPortal, dirLeft );
				funnelRight.set( currPortal, dirRight );
				++currPortal;
				
				continue;
			} else if ( funnelRight.isOnLeft( dirRight ) ) {
				funnelRight.set( currPortal, dirRight );
			}
			++currPortal;
		}

		// Now handle goal
		const Vector2 goalPt = path->getGoalCentroid();
		Vector2 goalDir( goalPt - apex._pos );

		if ( funnelLeft.isOnLeft( goalDir ) ) {
			// The goal point is on the left side of the funnel
			if ( apex._id != -1 && apex._id < PORTAL_COUNT ) {
				path->setWaypoints( apex._id + 1, PORTAL_COUNT, apex._pos + funnelLeft._dir, norm( funnelLeft._dir ) );
			}
		} else if ( funnelRight.isOnRight( goalDir ) ) {
			// The goal point is on the right side of the funnel
			if ( apex._id != -1 && apex._id < PORTAL_COUNT ) {
				path->setWaypoints( apex._id + 1, PORTAL_COUNT, apex._pos + funnelRight._dir, norm( funnelRight._dir ) );
			}
		} 

		if ( apex._id + 1 < PORTAL_COUNT ) {
			path->setWaypoints( (size_t)apex._id + 1, (size_t)PORTAL_COUNT, goalPt, norm( goalPt - apex._pos ) );
		}

	#else
		_left.push_back( FunnelEdge( startPortal - 1, startPortal, dirLeft, startPos ) );
		_right.push_back( FunnelEdge( startPortal - 1, startPortal, dirRight, startPos ) );
		const size_t PORTAL_COUNT = path->getPortalCount();
		for ( size_t i = startPortal + 1; i < PORTAL_COUNT; ++i ) {
			portal = path->getPortal( i );

			// investigate the left point
			pLeft.set( portal->getLeft( radius ) );			
			bool apexMoved = false;
			while ( !_right.empty() ) {
				std::list< FunnelEdge >::iterator itr = _right.begin();
				Vector2 dir = pLeft - itr->_origin;
				if ( itr->isOnRight( dir ) ) {
					apexMoved = true;
					Vector2 newApex = itr->_origin + itr->_dir;
					path->setWaypoints( itr->_id + 1, itr->_endID + 1, newApex, norm( itr->_dir ) );
					apex.set( itr->_endID, newApex );
					_right.pop_front();
				} else {
					break;
				}
			}
			if ( apexMoved ) {
				_left.clear();
				_left.push_back( FunnelEdge( apex._id, i, pLeft - apex._pos, apex._pos ) );
			} else {
				std::list< FunnelEdge >::reverse_iterator itr = _left.rbegin();
				while ( ! _left.empty() ) {
					Vector2 dir = pLeft - itr->_origin;
					if ( itr->isOnRight( dir ) ) {
						_left.pop_back();
						itr = _left.rbegin();
					} else {
						break;
					}
				}
				if ( _left.empty() ) {
					_left.push_back( FunnelEdge( apex._id, i, pLeft - apex._pos, apex._pos ) );
				} else {
					Vector2 origin( itr->_origin + itr->_dir );
					_left.push_back( FunnelEdge( itr->_endID, i, pLeft - origin, origin ) );
				}
			}

			// investigate the right point
			pRight.set( portal->getRight( radius ) );
			apexMoved = false;
			while ( !_left.empty() ) {
				std::list< FunnelEdge >::iterator itr = _left.begin();
				Vector2 dir = pRight - itr->_origin;
				if ( itr->isOnLeft( dir ) ) {
					apexMoved = true;
					Vector2 newApex = itr->_origin + itr->_dir;
					path->setWaypoints( itr->_id + 1, itr->_endID + 1, newApex, norm( itr->_dir ) );
					apex.set( itr->_endID, newApex );
					_left.pop_front();
				} else {
					break;
				}
			}
			if ( apexMoved ) {
				_right.clear();
				_right.push_back( FunnelEdge( apex._id, i, pRight - apex._pos, apex._pos ) );
			} else {
				std::list< FunnelEdge >::reverse_iterator itr = _right.rbegin();
				while ( ! _right.empty() ) {
					Vector2 dir = pRight - itr->_origin;
					if ( itr->isOnLeft( dir ) ) {
						_right.pop_back();
						itr = _right.rbegin();
					} else {
						break;
					}
				}
				if ( _right.empty() ) {
					_right.push_back( FunnelEdge( apex._id, i, pRight - apex._pos, apex._pos ) );
				} else {
					Vector2 origin( itr->_origin + itr->_dir );
					_right.push_back( FunnelEdge( itr->_endID, i, pRight - origin, origin ) );
				}
			}
		}
		// handle the goal
		const Vector2 goalPt = path->getGoalCentroid();
		Vector2 goalDir;

		bool apexMoved = false;
		while ( !_left.empty() ) {
			std::list< FunnelEdge >::iterator itr = _left.begin();
			goalDir.set( goalPt - itr->_origin );
			if ( itr->isOnLeft( goalDir ) ) {
				apexMoved = true;
				Vector2 newApex = itr->_origin + itr->_dir;
				apex.set( itr->_endID, newApex );
				path->setWaypoints( itr->_id + 1, itr->_endID + 1, newApex, norm( itr->_dir ) );
				_left.pop_front();
			} else {
				break;
			}
		}
		if ( apexMoved ) {
			goalDir.set( goalPt - apex._pos );
			path->setWaypoints( apex._id + 1, PORTAL_COUNT, goalPt, norm( goalDir ) );
		} else {
			// apexMoved is already false -- it is the only way to reach this branch
			while ( !_right.empty() ) {
				std::list< FunnelEdge >::iterator itr = _right.begin();
				goalDir.set( goalPt - itr->_origin );
				if ( itr->isOnRight( goalDir ) ) {
					apexMoved = true;
					Vector2 newApex = itr->_origin + itr->_dir;
					apex.set( itr->_endID, newApex );
					path->setWaypoints( itr->_id + 1, itr->_endID + 1, newApex, norm( itr->_dir ) );
					_right.pop_front();
				} else {
					break;
				}
			}

			goalDir.set( goalPt - apex._pos );
			path->setWaypoints( apex._id + 1, PORTAL_COUNT, goalPt, norm( goalDir ) );

		}
	#endif	// SIMPLE_FUNNEL
	}
예제 #6
0
void Pyramid::createPyramid()
{
	//Vertices
	Vect apex(0.0f, 7.07f, 0.0f);
	Vect frontLeft(-5.0f, 0.0f, 5.0f);
	Vect frontRight(5.0f, 0.0f, 5.0f);
	Vect backLeft(-5.0f, 0.0f, -5.0f);
	Vect backRight(5.0f, 0.0f, -5.0f);

	//Normals
	Vect frontNormal = (frontRight - frontLeft).cross(apex - frontRight);
	Vect rightNormal = (backRight - frontRight).cross(apex - backRight);
	Vect backNormal = (backLeft - backRight).cross(apex - backLeft);
	Vect leftNormal = (frontLeft - backLeft).cross(apex - frontLeft);
	Vect bottomNormal1 = (frontLeft - frontRight).cross(backLeft - frontLeft);
	Vect bottomNormal2 = (backRight - backLeft).cross(frontRight - backRight);

	pyramidBatch.Begin(GL_TRIANGLES, 18, 1);

	//Front side of pyramid
	//Front left
	pyramidBatch.Normal3f(frontNormal[x], frontNormal[y], frontNormal[z]);
	pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
	pyramidBatch.Vertex3f(frontLeft[x], frontLeft[y], frontLeft[z]);

	//Front right
	pyramidBatch.Normal3f(frontNormal[x], frontNormal[y], frontNormal[z]);
	pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
	pyramidBatch.Vertex3f(frontRight[x], frontRight[y], frontRight[z]);

	//Apex
	pyramidBatch.Normal3f(frontNormal[x], frontNormal[y], frontNormal[z]);
	pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
	pyramidBatch.Vertex3f(apex[x], apex[y], apex[z]);

	//Right side of pyramid
	//Front right
	pyramidBatch.Normal3f(rightNormal[x], rightNormal[y], rightNormal[z]);
	pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
	pyramidBatch.Vertex3f(frontRight[x], frontRight[y], frontRight[z]);

	//Back right
	pyramidBatch.Normal3f(rightNormal[x], rightNormal[y], rightNormal[z]);
	pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
	pyramidBatch.Vertex3f(backRight[x], backRight[y], backRight[z]);

	//Apex
	pyramidBatch.Normal3f(rightNormal[x], rightNormal[y], rightNormal[z]);
	pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
	pyramidBatch.Vertex3f(apex[x], apex[y], apex[z]);

	//Back side of pyramid
	//Back right
	pyramidBatch.Normal3f(backNormal[x], backNormal[y], backNormal[z]);
	pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
	pyramidBatch.Vertex3f(backRight[x], backRight[y], backRight[z]);

	//Back left
	pyramidBatch.Normal3f(backNormal[x], backNormal[y], backNormal[z]);
	pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
	pyramidBatch.Vertex3f(backLeft[x], backLeft[y], backLeft[z]);

	//Apex
	pyramidBatch.Normal3f(backNormal[x], backNormal[y], backNormal[z]);
	pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
	pyramidBatch.Vertex3f(apex[x], apex[y], apex[z]);

	//Left side of pyramid
	//Back left
	pyramidBatch.Normal3f(leftNormal[x], leftNormal[y], leftNormal[z]);
	pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
	pyramidBatch.Vertex3f(backLeft[x], backLeft[y], backLeft[z]);

	//Front left
	pyramidBatch.Normal3f(leftNormal[x], leftNormal[y], leftNormal[z]);
	pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
	pyramidBatch.Vertex3f(frontLeft[x], frontLeft[y], frontLeft[z]);

	//Apex
	pyramidBatch.Normal3f(backNormal[x], backNormal[y], backNormal[z]);
	pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);
	pyramidBatch.Vertex3f(apex[x], apex[y], apex[z]);

	//Bottom 1 of pyramid
	//Front right
	pyramidBatch.Normal3f(bottomNormal1[x], bottomNormal1[y], bottomNormal1[z]);
	pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
	pyramidBatch.Vertex3f(frontRight[x], frontRight[y], frontRight[z]);

	//Front left
	pyramidBatch.Normal3f(bottomNormal1[x], bottomNormal1[y], bottomNormal1[z]);
	pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
	pyramidBatch.Vertex3f(frontLeft[x], frontLeft[y], frontLeft[z]);

	//Back left
	pyramidBatch.Normal3f(bottomNormal1[x], bottomNormal1[y], bottomNormal1[z]);
	pyramidBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
	pyramidBatch.Vertex3f(backLeft[x], backLeft[y], backLeft[z]);

	//Bottom 2 of pyramid
	//Back left
	pyramidBatch.Normal3f(bottomNormal2[x], bottomNormal2[y], bottomNormal2[z]);
	pyramidBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
	pyramidBatch.Vertex3f(backLeft[x], backLeft[y], backLeft[z]);

	//Back right
	pyramidBatch.Normal3f(bottomNormal2[x], bottomNormal2[y], bottomNormal2[z]);
	pyramidBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
	pyramidBatch.Vertex3f(backRight[x], backRight[y], backRight[z]);

	//Front right
	pyramidBatch.Normal3f(bottomNormal2[x], bottomNormal2[y], bottomNormal2[z]);
	pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
	pyramidBatch.Vertex3f(frontRight[x], frontRight[y], frontRight[z]);

	pyramidBatch.End();
}
예제 #7
0
파일: tin.cpp 프로젝트: cugwhp/terrace
double TIN::interpolate(double theX, double theY) const
{

////////////////////////////////////////////////////////////////////////////////
int plus1mod3[3] = {1, 2, 0};
int minus1mod3[3] = {2, 0, 1};

#define org(otri, vertexptr)                                                  \
  vertexptr = (vertex) (otri).tri[plus1mod3[(otri).orient] + 3]

#define dest(otri, vertexptr)                                                 \
  vertexptr = (vertex) (otri).tri[minus1mod3[(otri).orient] + 3]

#define apex(otri, vertexptr)                                                 \
  vertexptr = (vertex) (otri).tri[(otri).orient + 3]
////////////////////////////////////////////////////////////////////////////////
	
	double z;
	TVertex v;
	TVertex t1;
	TVertex t2;
	TVertex t3;
	wykobi::segment<double, 3> segment;
	wykobi::triangle<double, 3> triangle;

	v = static_cast<TVertex>(new double[2]);
	v[0] = theX;
	v[1] = theY;

	switch (preciselocate(mMesh, mBehavior, v, mRecentTri, 0)) {
		case ONVERTEX:
			org(*mRecentTri, t1);
			// Take elevation of vertex
			z = t1[2];
			// delete [] t1;
			break;
		case ONEDGE:
			// Interpolate elevation on edge
			org(*mRecentTri, t1);
			dest(*mRecentTri, t2);
			segment = wykobi::make_segment(t1[0], t1[1], t1[2], 
				t2[0], t2[1], t2[2]);
			z = interpolateOnSegment(segment, theX, theY);
			// delete [] t1;
			// delete [] t2;
			break;
		case INTRIANGLE:
			// Interpolate elevation on triangle
			org(*mRecentTri, t1);
			dest(*mRecentTri, t2);
			apex(*mRecentTri, t3);
			triangle = wykobi::make_triangle(t1[0], t1[1], t1[2], 
				t2[0], t2[1], t2[2], t3[0], t3[1], t3[2]); 
			z = interpolateInTriangle(triangle, theX, theY);
			// delete [] t1;
			// delete [] t2;
			// delete [] t3;
			break;
		case OUTSIDE:
			z = -1 * std::numeric_limits<double>::max(); 
			break;
	}

	delete [] v;

	return z;
}