Пример #1
0
//Convenience Constructor
QuatCamera::QuatCamera():
    yAxis{ 0.0f, 1.0f, 0.0f },
    position{ 7.0f, 4.0f, 20.0f },
    forward{ 0.0f, 0.0f, -1.0f },
    up{ 0.0f, 1.0f, 0.0f },
    MOVEMENT_SPEED(0.1f), ROTATION_SPEED(0.0025f), SPIN_SPEED(40.0f),
    slerping(false)
{
    up = getNormalized(up);
    forward = getNormalized(forward);
}
Пример #2
0
QuatCamera::QuatCamera(glm::vec3 pos, glm::vec3 up_, glm::vec3 forward_) :
    yAxis{ 0.0f, 1.0f, 0.0f },
    position{ pos },
    forward{ forward_ },
    up{ up_ },
    MOVEMENT_SPEED(0.1f), ROTATION_SPEED(0.0025f), SPIN_SPEED(40.0f),
    slerping(false)
{
    up = getNormalized(up);
    forward = getNormalized(forward);
}
Пример #3
0
void Osg3dView::mousePressEvent(QMouseEvent *event)
{
    vDebug("mousePressEvent");

    if (event->button() == Qt::LeftButton) {

        m_savedEventNDCoords = getNormalized(event->x(), event->y());

        // always identify the item under the mouse in case
        // it is a drag object
        findObjectsUnderMouseEvent();

        // if np.at(1) != loadedModel we are dragging/clicking some control
        // in that case we want to stash the current mouse mode, do the drag
        // and restore the mouse mode when we are done.

        // Do the job asked
        if (m_mouseMode & (MM_PAN|MM_ROTATE|MM_ORBIT|MM_ZOOM) )
            m_viewingCore->setPanStart( m_savedEventNDCoords.x(),
                                        m_savedEventNDCoords.y());
        else if (m_mouseMode & MM_PICK_CENTER) {
            m_viewingCore->pickCenter(m_savedEventNDCoords.x(),
                                      m_savedEventNDCoords.y() );
            update();
        } else if (m_mouseMode & MM_SELECT) {
            // In this case we probably want to skip any intersections with
            // objects other than those under loadedModel;
            pickAnObjectFromView();
        }

        m_mouseIsPressed = true;
    }
}
Пример #4
0
void Quaternion::fromMatrix(const Matrix &m) {
    Real trace = m[0] + m[5] + m[10] + 1.0;
    Real s = .5;
    
    if (!Math::eq(trace, 0)) {
        s /= Math::Sqrt(trace);
        w = 0.25 / s;
        x = (m[6] - m[9]) * s;
        y = (m[8] - m[2]) * s;
        z = (m[1] - m[4]) * s;
    } else {
        if((m[0] > m[5]) && (m[0] > m[10]) ) {
            s /= Math::Sqrt( 1.0 + m[0] - m[5] - m[10] );
            x = 0.25 / s;
            y = (m[4] + m[1]) * s;
            z = (m[8] + m[2]) * s;
            w = (m[9] - m[6]) * s;
        } else if(m[5] > m[10]) {
            s /= Math::Sqrt( 1.0 + m[5] - m[0] - m[10] );
            x = (m[4] + m[1]) * s;
            y = 0.25 / s;
            z = (m[9] + m[6]) * s;
            w = (m[8] - m[2]) * s;
        } else {
            s /= Math::Sqrt( 1.0 + m[10] - m[0] - m[5] );
            x = (m[8] + m[2]) * s;
            y = (m[9] + m[6]) * s;
            z = 0.25 / s;
            w = (m[4] - m[1]) * s;
        }
    }
    normalize();
    // The resulting quaternion should be already normalized.
    ASSERT_EQ(*this, getNormalized());
}
Пример #5
0
    void Shot::onCollision(const Collision & c)
    {
        sf::Color clr(255,255,255);

        if(c.entity != NULL)
        {
            // Except entities with the same team or the same type
            if(c.entity->team == team || c.entity->getType() == getType())
                return;

            if(c.entity->getType() != ENT_MAP)
            {
                // Repulsion
                Vector2f repulsion = getNormalized(speed);
                // TODO find a way to access delta here, or not have to.
                // onCollision basically doesn't access to delta, then we have to choose a value...
                c.entity->accelerate(repulsion * 80.f, 0.03f);

                // Hurting
                Message hurt(M_HEA_HURT, this);
                hurt.health = 15;
                c.entity->processMessage(hurt);

                // Bloody color
                clr.g = 0;
                clr.b = 0;
            }
        }

        // Hit particles
        r_level->spawnEntity(new entity::ShockWave(0.1, 0.8, 4, clr), pos);

        invalidate();
    }
Пример #6
0
void Osg3dView::mouseReleaseEvent(QMouseEvent *event)
{
    vDebug("mouseReleaseEvent");
    m_savedEventNDCoords = getNormalized(event->x(), event->y());

    if (event->button() == Qt::LeftButton)
        m_mouseIsPressed = false;
}
Пример #7
0
float Vec2::getAngle(const Vec2& other) const
{
    Vec2 a2 = getNormalized();
    Vec2 b2 = other.getNormalized();
    float angle = atan2f(a2.cross(b2), a2.dot(b2));
    if( fabs(angle) < FLT_EPSILON ) return 0.f;
    return angle;
}
Пример #8
0
void Quaternion::invert() {
    // make sure we only try this with normalized quaternions. If the quat is not of unit
    // length, the method of inverting changes.
    ASSERT_EQ(*this, getNormalized());
    x = -x;
    y = -y;
    z = -z;
}
Пример #9
0
float toxi::geom::Vec2D::angleBetween( Vec2D v, bool forceNormalize )
{
	double theta;
	if (forceNormalize) {
		theta = getNormalized().dot(v.getNormalized());
	} else {
		theta = dot(v);
	}
	return (float) std::acos(toxi::math::MathUtils::clipNormalized(theta));
}
Пример #10
0
//Increments the slerp
void QuatCamera::updateSlerp(atlas::utils::Time const& t) {
    slerpProgress += t.deltaTime / SLERP_DURATION;
    //Slerping Complete
    if ((slerpProgress >= 1.0f) || equals(getNormalized(target - position), forward)) {
        slerping = false;
        slerpProgress = 0.0000000000f;
    }
    else {
        doSlerp(t);
    }
}
Пример #11
0
void Quaternion::apply(Vector3 &vector) const {
    // make sure we only try this with normalized quaternions. If the quat is not of unit
    // length, the method of inverting changes.
    ASSERT_EQ(*this, getNormalized());

    // Tansform the vector into the 4th dimension, apply the rotation, and transform back.
    Quaternion q = (*this) * Quaternion(0, vector.x, vector.y, vector.z) * Quaternion(w, -x, -y, -z);
    vector.x = q.x;
    vector.y = q.y;
    vector.z = q.z;
}
Пример #12
0
float TExamplesDistance_DTW::operator ()(const TExample &e1, const TExample &e2) const
{ 
  vector<float> seq1, seq2, der1, der2;
  getNormalized(e1, seq1);
  getNormalized(e2, seq2);
  TdtwMatrix mtrx;
  switch (dtwDistance) {
	case DTW_EUCLIDEAN: {
	  initMatrix(seq1, seq2, mtrx);
	  break;
						}
	case DTW_DERIVATIVE: {
		getDerivatives(seq1, der1);
		getDerivatives(seq2, der2);
		initMatrix(der1, der2, mtrx);
		break;
						 }
  }
  float dist = calcDistance(mtrx);
  return dist;
}
Пример #13
0
	Quaternion QuaternionFn::getAngleAxis(const Radian& angle, const Vector3& axis)
	{
		Quaternion q;

		const Vector3 a = getNormalized(axis);

		const float s = MathFn::sin(0.5f * angle);

		q.xyz = a * s;
		q.w = MathFn::cos(0.5f * angle);

		return q;
	}
Пример #14
0
void Quaternion::fromAngleAxis(const Radian &angle, const Vector3 &axis) {
    // This is used to compensate for a non-unit axis.
    Real oneOverLength = 1.0f / axis.length();
    Real sinAngle = Math::Sin(angle * 0.5f);
    
    w = Math::Cos(angle * 0.5f);
    x = (axis.x * sinAngle) * oneOverLength;
    y = (axis.y * sinAngle) * oneOverLength;
    z = (axis.z * sinAngle) * oneOverLength;

    // The resulting quaternion should be already normalized.
    ASSERT_EQ(*this, getNormalized());
}
Пример #15
0
void LayerGradientTest::onTouchesMoved(const std::vector<Touch*>& touches, Event *event)
{
    auto s = Director::getInstance()->getWinSize();

    auto touch = touches[0];
    auto start = touch->getLocation();    

    auto diff =  Vec2(s.width/2,s.height/2) - start;
    diff = diff.getNormalized();

    auto gradient = static_cast<LayerGradient*>( getChildByTag(1) );
    gradient->setVector(diff);
}
Пример #16
0
void solvePaddleBallCollision(const Paddle& mPaddle, Ball& mBall) noexcept
{
    if(!isIntersecting(mPaddle, mBall)) return;

    auto newY(mPaddle.top() - mBall.shape.getRadius() * 2.f);
    mBall.shape.setPosition(mBall.x(), newY);

    auto paddleBallDiff(mBall.x() - mPaddle.x());
    auto posFactor(paddleBallDiff / mPaddle.width());
    auto velFactor(mPaddle.velocity.x * 0.05f);

    sf::Vector2f collisionVec{posFactor + velFactor, -2.f};
    mBall.velocity = getReflected(mBall.velocity, getNormalized(collisionVec));
}
Пример #17
0
    /**
     * @brief cumulativef computes the cumulative Histogram.
     * @param bNormalized is a boolean value; if it is true values of
     * the Histogram will be normalized.
     * @return It returns the cumulative Histogram as a float pointer.
     */
    float *cumulativef(bool bNormalized)
    {
        getNormalized();
    
        bin_c = Array<float>::cumsum(bin_nor, nBin, bin_c);

        if(bNormalized) {
            for(int i=0; i<nBin; i++) {
                bin_c[i] /= bin_c[nBin - 1];
            }
        }

        return bin_c;
    }
Пример #18
0
    /**
     * @brief write saves the Histogram as an Image into a file.
     * @param name is the filename where to save the Histogram.
     * @param bNor is a boolean value for normalizing or not the Histogram.
     */
    void write(std::string name, bool bNor)
    {
        Image img(1, nBin, 1, 1);

        if(bNor) {
            getNormalized();
            memcpy(img.data, bin_nor, sizeof(float)*nBin);
        } else {
            for(int i = 0; i < nBin; i++) {
                img.data[i] = float(bin[i]);
            }
        }

        img.Write(name, LT_NONE);
    }
Пример #19
0
void OSGWidget::mouseReleaseEvent( QMouseEvent* event )
{
    m_mouseReleaseJustHappened = true;

    m_lastMouseEventNDCoords = getNormalized(event->x(), event->y());

    m_mouseButtons &= event->buttons();

    if (m_mouseModifiers != Qt::NoModifier) {
        popState();
    }

    m_mouseModifiers = Qt::NoModifier;
    m_lastMouseEventTime.start();
}
Пример #20
0
void Quaternion::fromEuler(const Radian &nx, const Radian &ny, const Radian &nz) {
    Real sx = Math::Sin(nx * .5);
    Real sy = Math::Sin(ny * .5);
    Real sz = Math::Sin(nz * .5);
    Real cx = Math::Cos(nx * .5);
    Real cy = Math::Cos(ny * .5);
    Real cz = Math::Cos(nz * .5);
    
    w = (cz * cy * cx) + (sz * sy * sx);
    x = (cz * cy * sx) - (sz * sy * cx);
    y = (cz * sy * cx) + (sz * cy * sx);
    z = (sz * cy * cx) - (cz * sy * sx);

    // The resulting quaternion should be already normalized.
    ASSERT_EQ(*this, getNormalized());
}
Пример #21
0
/******************
 *Euler Conversion*
 ******************/
void Quaternion::toEuler(Radian &nx, Radian &ny, Radian &nz) {
    // make sure we only try this with normalized quaternions
    ASSERT_EQ(*this, getNormalized());

    ny = -Math::Asin(2.0 * ((x * z) - (w * y)));
    Real cy = Math::Cos(ny);

    if(Math::eq(cy, 0)) { //Gimbal Lock
        nx = 0.0;
        nz = Math::Atan2(((x * y) - (w * z)) * 2.0, (1.0 - (x * x) - (z * z)) * 2.0);
    } else {
        Real twoInvCy = 2.0 / cy;
        nx = -Math::Atan2(((y * z) + (w * x)) * twoInvCy, (0.5 - (x * x) - (y * y)) * twoInvCy);
        nz =  Math::Atan2(((x * y) + (w * z)) * twoInvCy, (0.5 - (y * y) - (z * z)) * twoInvCy);
    }
}
Пример #22
0
void Quaternion::toAngleAxis(Radian &angle, Real &nx, Real &ny, Real &nz) {
    // make sure we only try this with normalized quaternions
    ASSERT_EQ(*this, getNormalized());

    angle = Math::Acos(w) * 2.0;
    Real oneOverLength = Math::Sqrt((x * x) + (y * y) + (z * z));
    nx = x * oneOverLength;
    ny = y * oneOverLength;
    nz = z * oneOverLength;

    oneOverLength = 1.0 / Math::Sqrt((nx * nx) + (ny * ny) + (nz * nz));
    nx *= oneOverLength;
    ny *= oneOverLength;
    nz *= oneOverLength;

    // The resulting axis should be normalized already.
    ASSERT_EQ(Vector3(nx, ny, nz), Vector3(nx, ny, nz).getNormalized());
}
Пример #23
0
void OSGWidget::mousePressEvent( QMouseEvent* event )
{
    m_animateTimer.stop();

    m_mouseReleaseJustHappened = false;

    m_lastMouseEventNDCoords = getNormalized(event->x(), event->y());

    m_mouseButtons |= event->buttons();

    m_mouseModifiers = event->modifiers();

    // handle overrides
    if (m_mouseButtons == Qt::LeftButton) {
        if (m_mouseModifiers == Qt::ShiftModifier) {
            pushState();
            m_viewingCore->setViewingCoreMode(ViewingCore::THIRD_PERSON);
            setMouseMode(MM_PAN);
        } else if (m_mouseModifiers == Qt::ControlModifier) {
            pushState();
            m_viewingCore->setViewingCoreMode(ViewingCore::THIRD_PERSON);
            setMouseMode(MM_ORBIT);
        } else if ((unsigned)m_mouseModifiers == (unsigned)(Qt::ControlModifier | Qt::ShiftModifier) ) {
            pushState();
            m_viewingCore->setViewingCoreMode(ViewingCore::THIRD_PERSON);
            setMouseMode(MM_ZOOM);
        }
    } else if (m_mouseButtons == Qt::RightButton) {
        m_viewingCore->pickCenter(m_lastMouseEventNDCoords.x(),
                                  m_lastMouseEventNDCoords.y() );
    }

    // Do the job asked
    if (m_mouseMode & (MM_PAN|MM_ROTATE|MM_ORBIT|MM_ZOOM) )
        m_viewingCore->setPanStart( m_lastMouseEventNDCoords.x(), m_lastMouseEventNDCoords.y() );
    else if (m_mouseMode & MM_PICK_CENTER) {
        m_viewingCore->pickCenter(m_lastMouseEventNDCoords.x(),
                                  m_lastMouseEventNDCoords.y() );
    }

    m_lastMouseEventTime.start();
}
Пример #24
0
void Enemy::updateMovement(){
	auto target = getTarget();
	if (!target) {
		if (velocity.getLengthSq() != 0.f)
			return;
		velocity = Vec2::ZERO;
	}
	else {
		auto delta = target->position - position;
		velocity = delta.getNormalized() * _ATTR(speed);
	}

	MoveNoti noti;
	noti.id = id;
	noti.start_x = position.x;
	noti.start_y = position.y;
	noti.velocity_x = velocity.x;
	noti.velocity_y = velocity.y;
	stage->gameroom->sendPacket(noti);
}
Пример #25
0
void Osg3dView::mouseMoveEvent(QMouseEvent *event)
{
    vDebug("mouseMoveEvent");
    osg::Vec2d currentNDC = getNormalized(event->x(), event->y());
    osg::Vec2d delta = currentNDC - m_savedEventNDCoords;

    switch (m_mouseMode) {
    case MM_ORBIT:
        m_viewingCore->rotate( m_savedEventNDCoords, delta);
        break;
    case MM_PAN:
        m_viewingCore->pan(delta.x(), delta.y());
        break;
    case MM_ZOOM: {
        double tempScale = m_viewingCore->getFovyScale();
        m_viewingCore->setFovyScale(1.03);

        if(delta.y() > 0)
            m_viewingCore->fovyScaleDown();

        if(delta.y() < 0)
            m_viewingCore->fovyScaleUp();

        m_viewingCore->setFovyScale(tempScale);
        break;
    }
    case MM_ROTATE:
        m_viewingCore->rotate(  m_savedEventNDCoords, delta );
        break;
    default:
        break;
    }

    m_savedEventNDCoords = currentNDC;
    update();
}
Пример #26
0
cocos2d::Vec2 SteeringBehaviors::separation()
{
    Vec2 tmpForce;
    auto tmpIterator    =   EntityMgr->getEntityMap()->begin();
    for (; tmpIterator != EntityMgr->getEntityMap()->end(); tmpIterator++)
    {
        auto tmpCharacter   =   dynamic_cast<GameCharacter*>(tmpIterator->second);
        if (tmpCharacter == m_pOwner || !isNeighbor(tmpCharacter))
        {
            continue;
        }

        auto tmpToOwner =   m_pOwner->getMovingEntity().getPosition() - tmpCharacter->getMovingEntity().getPosition();
        // 这个驱动力与该角色到owner的距离成反比(注意这里的距离是减去了两个半径后)
        auto tmpLen     =   tmpToOwner.getLength() - (m_pOwner->getMovingEntity().getRadius() + tmpCharacter->getMovingEntity().getRadius());
        if (tmpLen <= 0)
        {
            tmpLen  =   1;
        }
        tmpForce        +=  m_separationMagnify * tmpToOwner.getNormalized() / tmpLen;
    }

    return tmpForce;
}
Пример #27
0
void Graph::draw(int x, int y) {
	ofPushMatrix();
	ofPushStyle();
	ofTranslate(x, y);
	
	drawPosition = worldToScreen(ofVec2f(0, 0));
	
	ofFill();
	ofSetColor(ofMap(ofGetElapsedTimef() - lastTrigger, 0, .5, 255, 0, true));
	if(noData) {
		ofSetColor(128);
	}
	ofRect(0, 0, width, height);
	
	ofNoFill();
	ofSetColor(255);
	ofPushStyle();
//	if(hoverState) {
//		ofSetHexColor(0xffee00);
//		ofSetLineWidth(2);
//	}
	ofRect(0, 0, width, height);
	ofPopStyle();
	
	ofRectangle region(1, height - 1, width - 2, -(height - 2));
	ofSetHexColor(0xec008c);
	if(noData) {
		ofSetColor(200);
	}
	drawBuffer(derivativePolyline, threshold, derivativeBox, region);
	ofSetColor(255);
	drawBuffer(bufferPolyline, 0, bufferBox, region);
	
	ofSetColor(255);
	drawString(name, 5, 10);
	
	if(!buffer.empty() && !derivative.empty()) {
		ofPushMatrix();
		ofTranslate(width, 0);
		drawString(ofToString(bufferBox.y, 2) + "<" + (buffer.empty() ? "empty" :  ofToString(buffer.back(), 2)) + "<" + ofToString(bufferBox.y + bufferBox.height, 2), 5, 10);
		drawString(ofToString(derivativeBox.y, 2) + "<" + (derivative.empty() ? "empty" :  ofToString(derivative.back(), 2)) + "<" + ofToString(derivativeBox.y + derivativeBox.height, 2), 5, 18);
		drawString(ofToString(threshold, 2) + ", " + ofToString(buffer.back(), 2) + " (" + ofToString(getNormalized(), 2) + ") " + ofToString(derivative.back(), 2), 5, 26);
		ofPopMatrix();
	}
	
	ofPopStyle();
	ofPopMatrix();
}
Пример #28
0
float C3Vector::getAngle(const C3Vector& v) const
{ // Return value is in radian!!
	C3Vector a(getNormalized());
	C3Vector b(v.getNormalized());
	return(CMath::robustAcos(a*b));
}
Пример #29
0
void Fl_Gto::show() const {
  TlLogging& log = TlLogging::getInstance();

  std::stringstream ss;
  int angular;

  ss << "----------------------------------------------------------------------"
        "--\n";
  ss << " numbercgto     : " + TlUtils::xtos(this->getNumOfCGTOs()) + "\n";
  ss << "----------------------------------------------------------------------"
        "--\n";
  for (int i = 0; i < this->getNumOfCGTOs(); i++) {
    ss << " --- " << i << " th CGTO --------------------\n";
    ss << "Snum [" << this->cgto[i].Snum << "]\n";
    ss << "Pnum [" << this->cgto[i].Pnum << "]\n";
    ss << "Dnum [" << this->cgto[i].Dnum << "]\n";
    ss << "basis             [" << cgto[i].basisName << "]\n";
    ss << "atom              [" << cgto[i].atom << "]\n";
    ss << "label             [" << cgto[i].label << "]\n";
    ss << "shellname         [" << cgto[i].shellname << "]\n";
    ss << "shell              " << cgto[i].shell << " \n";

    ss << TlUtils::format("  scale factor     = %18.8lf\n",
                          cgto[i].scalefactor);
    ss << TlUtils::format("  contraction      = %18ld\n",
                          cgto[i].contraction());
    ss << "  <normalizedfactor> ";

    if (getShell(i) == 's') {
      angular = 0;
    } else if (getShell(i) == 'p') {
      angular = 1;
    } else if (getShell(i) == 'd') {
      angular = 2;
    } else if (getShell(i) == 'f') {
      angular = 3;
    } else {
      ss << " *** Fl_Gto::show() not supported such large shell.\n";
      ss << "     +++ calculate in case of l=m=n=0, and continue.\n";
      angular = 0;
    }
    for (int l = 0; l <= angular; l++) {
      for (int m = 0; m <= angular; m++) {
        for (int n = 0; n <= angular; n++) {
          if (l + m + n == angular) {
            ss << TlUtils::format("  (%1ld,%1ld,%1ld) = %18.8lE ", l, m, n,
                                  getNormalizedfactor(i, l, m, n));
          }
        }
      }
    }
    ss << "\n";
    ss << "    // primitive GTO //\n";

    for (int j = 0; j < cgto[i].contraction(); j++) {
      ss << TlUtils::format("      %18.8lE %18.8lE \n",
                            this->cgto[i].pgto[j].exponent,
                            this->cgto[i].pgto[j].coefficient);
      ss << "  <normalized> ";

      if (getShell(i) == 's')
        angular = 0;
      else if (getShell(i) == 'p')
        angular = 1;
      else if (getShell(i) == 'd')
        angular = 2;
      else if (getShell(i) == 'f')
        angular = 3;
      else {
        ss << " *** Fl_Gto::show() not supported such large shell.\n";
        ss << "     +++ calculate in case of l=m=n=0, and continue.\n";
        angular = 0;
      }
      for (int l = 0; l <= angular; l++) {
        for (int m = 0; m <= angular; m++) {
          for (int n = 0; n <= angular; n++) {
            if (l + m + n == angular) {
              ss << TlUtils::format("  (%1ld,%1ld,%1ld) = %18.8lE %18.8lE \n",
                                    l, m, n, getNormalized(i, j, l, m, n),
                                    getCoulombnormalized(i, j, l, m, n));
            }
          }
        }
      }
      ss << "\n";
    }
  }
  ss << " ---------------------------------------------------------------------"
        "---\n";

  log.info(ss.str());
}
Пример #30
0
/******************************************************************************
 * Render the current scene
 * uses the global variables from the parser
 *****************************************************************************/
int ntlWorld::renderScene( void )
{
#ifndef ELBEEM_PLUGIN
	char nrStr[5];														// nr conversion 
	std::ostringstream outfn_conv("");  			// converted ppm with other suffix 
  ntlRenderGlobals *glob;                  	// storage for global rendering parameters 
  myTime_t timeStart,totalStart,timeEnd; 		// measure user running time 
  myTime_t rendStart,rendEnd;            		// measure user rendering time 
  glob = mpGlob;

	// deactivate for all with index!=0 
	if((glob_mpactive)&&(glob_mpindex>0)) return(0);

	/* check if picture already exists... */
	if(!glob->getSingleFrameMode() ) {
		snprintf(nrStr, 5, "%04d", glob->getAniCount() );

		if(glob_mpactive) {
			outfn_conv  << glob->getOutFilename() <<"_"<<glob_mpindex<<"_" << nrStr << ".png"; /// DEBUG!
		} else {
			// ORG
			outfn_conv  << glob->getOutFilename() <<"_" << nrStr << ".png";
		}
		
		//if((mpGlob->getDisplayMode() == DM_RAY)&&(mpGlob->getFrameSkip())) {
		if(mpGlob->getFrameSkip()) {
			struct stat statBuf;
			if(stat(outfn_conv.str().c_str(),&statBuf) == 0) {
				errorOut("ntlWorld::renderscene Warning: file "<<outfn_conv.str()<<" already exists - skipping frame..."); 
				glob->setAniCount( glob->getAniCount() +1 );
				return(2);
			}
		} // RAY mode
	} else {
		// single frame rendering, overwrite if necessary...
		outfn_conv << glob->getSingleFrameFilename();
	}

  /* start program */
	timeStart = getTime();

	/* build scene geometry, calls buildScene(t,false) */
	glob->getRenderScene()->prepareScene(mSimulationTime);

  /* start program */
	totalStart = getTime();


	/* view parameters are currently not animated */
	/* calculate rays through projection plane */
	ntlVec3Gfx direction = glob->getLookat() - glob->getEye();
	/* calculate width of screen using perpendicular triangle diven by
	 * viewing direction and screen plane */
	gfxReal screenWidth = norm(direction)*tan( (glob->getFovy()*0.5/180.0)*M_PI );

	/* calculate vector orthogonal to up and viewing direction */
	ntlVec3Gfx upVec = glob->getUpVec();
	ntlVec3Gfx rightVec( cross(upVec,direction) );
	normalize(rightVec);

	/* calculate screen plane up vector, perpendicular to viewdir and right vec */
	upVec = ntlVec3Gfx( cross(rightVec,direction) );
	normalize(upVec);

	/* check if vectors are valid */
	if( (equal(upVec,ntlVec3Gfx(0.0))) || (equal(rightVec,ntlVec3Gfx(0.0))) ) {
		errMsg("ntlWorld::renderScene","Invalid viewpoint vectors! up="<<upVec<<" right="<<rightVec);
		return(1);
	}

	/* length from center to border of screen plane */
	rightVec *= (screenWidth*glob->getAspect() * -1.0);
	upVec *= (screenWidth * -1.0);

	/* screen traversal variables */
	ntlVec3Gfx screenPos;                          /* current position on virtual screen */
	int Xres = glob->getResX();                  /* X resolution */
	int Yres = glob->getResY();                  /* Y resolution */
	ntlVec3Gfx rightStep = (rightVec/(Xres/2.0));  /* one step right for a pixel */
	ntlVec3Gfx upStep    = (upVec/(Yres/2.0));     /* one step up for a pixel */
    

	/* anti alias init */
	char  showAAPic = 0;
	int   aaDepth = glob->getAADepth();
	int   aaLength;
	if(aaDepth>=0) aaLength = (2<<aaDepth);
	else           aaLength = 0;
	float aaSensRed   = 0.1;
	float aaSensGreen = 0.1;
	float aaSensBlue  = 0.1;
	int   aaArrayX = aaLength*Xres+1;
	int   aaArrayY = ( aaLength+1 );
	ntlColor *aaCol = new ntlColor[ aaArrayX*aaArrayY ];
	char  *aaUse = new char[ aaArrayX*aaArrayY ];

	/* picture storage */
	int picX = Xres;
	int picY = Yres;
	if(showAAPic) {
		picX = Xres *aaLength+1;
		picY = Yres *aaLength+1;
	}
	ntlColor *finalPic = new ntlColor[picX * picY];


	/* reset picture vars */
	for(int j=0;j<aaArrayY;j++) {
		for(int i=0;i<aaArrayX;i++) {
			aaCol[j*aaArrayX+i] = ntlColor(0.0, 0.0, 0.0);
			aaUse[j*aaArrayX+i] = 0;
		}
	}
	for(int j=0;j<picY;j++) {
		for(int i=0;i<picX;i++) {
			finalPic[j*picX+i] = ntlColor(0.0, 0.0, 0.0);
		}
	}

	/* loop over all y lines in screen, from bottom to top because
	 * ppm format wants 0,0 top left */
	rendStart = getTime();
	glob->setCounterShades(0);
	glob->setCounterSceneInter(0);
	for (int scanline=Yres ; scanline > 0 ; --scanline) {
    
		debugOutInter( "ntlWorld::renderScene: Line "<<scanline<<
								 " ("<< ((Yres-scanline)*100/Yres) <<"%) ", 2, 2000 );
		screenPos = glob->getLookat() + upVec*((2.0*scanline-Yres)/Yres)
			- rightVec;

		/* loop over all pixels in line */
		for (int sx=0 ; sx < Xres ; ++sx) {

			if((sx==glob->getDebugPixelX())&&(scanline==(Yres-glob->getDebugPixelY()) )) {
				// DEBUG!!!
				glob->setDebugOut(10);
			} else glob->setDebugOut(0);
			
			/* compute ray from eye through current pixel into scene... */
			ntlColor col;
			if(aaDepth<0) {
				ntlVec3Gfx dir(screenPos - glob->getEye());
				ntlRay the_ray(glob->getEye(), getNormalized(dir), 0, 1.0, glob );

				/* ...and trace it */
				col = the_ray.shade();
			} else {
				/* anti alias */
				int ai,aj;                   /* position in grid */
				int aOrg = sx*aaLength;      /* grid offset x */
				int currStep = aaLength;     /* step size */
				char colDiff = 1;            /* do colors still differ too much? */
				ntlColor minCol,maxCol;         /* minimum and maximum Color Values */
				minCol = ntlColor(1.0,1.0,1.0);
				maxCol = ntlColor(0.0,0.0,0.0);

				while((colDiff) && (currStep>0)) {
					colDiff = 0;
	    
					for(aj = 0;aj<=aaLength;aj+= currStep) {
						for(ai = 0;ai<=aaLength;ai+= currStep) {

							/* shade pixel if not done */
							if(aaUse[aj*aaArrayX +ai +aOrg] == 0) {
								aaUse[aj*aaArrayX +ai +aOrg] = 1;
								ntlVec3Gfx aaPos( screenPos +
																(rightStep * (ai- aaLength/2)/(gfxReal)aaLength ) +
																(upStep    * (aj- aaLength/2)/(gfxReal)aaLength ) );

								ntlVec3Gfx dir(aaPos - glob->getEye());
								ntlRay the_ray(glob->getEye(), getNormalized(dir), 0, 1.0, glob );

								/* ...and trace it */
								ntlColor newCol= the_ray.shade();
								aaCol[aj*aaArrayX +ai +aOrg]= newCol;
							} /* not used? */

						}
					}

					/* check color differences */
					for(aj = 0;aj<aaLength;aj+= currStep) {
						for(ai = 0;ai<aaLength;ai+= currStep) {

							char thisColDiff = 0;
							if( 
								 (fabs(aaCol[aj*aaArrayX +ai +aOrg][0] - 
											 aaCol[(aj+0)*aaArrayX +(ai+currStep) +aOrg][0])> aaSensRed ) ||
								 (fabs(aaCol[aj*aaArrayX +ai +aOrg][1] - 
											 aaCol[(aj+0)*aaArrayX +(ai+currStep) +aOrg][1])> aaSensGreen ) ||
								 (fabs(aaCol[aj*aaArrayX +ai +aOrg][2] - 
											 aaCol[(aj+0)*aaArrayX +(ai+currStep) +aOrg][2])> aaSensBlue ) ) {
								thisColDiff = 1;
							} else
								if( 
									 (fabs(aaCol[aj*aaArrayX +ai +aOrg][0] - 
												 aaCol[(aj+currStep)*aaArrayX +(ai+0) +aOrg][0])> aaSensRed ) ||
									 (fabs(aaCol[aj*aaArrayX +ai +aOrg][1] - 
												 aaCol[(aj+currStep)*aaArrayX +(ai+0) +aOrg][1])> aaSensGreen ) ||
									 (fabs(aaCol[aj*aaArrayX +ai +aOrg][2] - 
												 aaCol[(aj+currStep)*aaArrayX +(ai+0) +aOrg][2])> aaSensBlue ) ) {
									thisColDiff = 1;
								} else
									if( 
										 (fabs(aaCol[aj*aaArrayX +ai +aOrg][0] - 
													 aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg][0])> aaSensRed ) ||
										 (fabs(aaCol[aj*aaArrayX +ai +aOrg][1] - 
													 aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg][1])> aaSensGreen ) ||
										 (fabs(aaCol[aj*aaArrayX +ai +aOrg][2] - 
													 aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg][2])> aaSensBlue ) ) {
										thisColDiff = 1;
									} 

							//colDiff =1;
							if(thisColDiff) {
								/* set diff flag */
								colDiff = thisColDiff;
								for(int bj=aj;bj<=aj+currStep;bj++) {
									for(int bi=ai;bi<=ai+currStep;bi++) {
										if(aaUse[bj*aaArrayX +bi +aOrg]==2) {
											//if(showAAPic) 
											aaUse[bj*aaArrayX +bi +aOrg] = 0;
										}
									}
								}
							} else {
								/* set all values */
								ntlColor avgCol = (
																	 aaCol[(aj+0       )*aaArrayX +(ai+0       ) +aOrg] +
																	 aaCol[(aj+0       )*aaArrayX +(ai+currStep) +aOrg] +
																	 aaCol[(aj+currStep)*aaArrayX +(ai+0       ) +aOrg] +
																	 aaCol[(aj+currStep)*aaArrayX +(ai+currStep) +aOrg] ) *0.25;
								for(int bj=aj;bj<=aj+currStep;bj++) {
									for(int bi=ai;bi<=ai+currStep;bi++) {
										if(aaUse[bj*aaArrayX +bi +aOrg]==0) {
											aaCol[bj*aaArrayX +bi +aOrg] = avgCol; 
											aaUse[bj*aaArrayX +bi +aOrg] = 2;
										}
									}
								}
							} /* smaller values set */

						}
					}

					/* half step size */
					currStep /= 2;

				} /* repeat until diff not too big */

				/* get average color */
				gfxReal colNum = 0.0;
				col = ntlColor(0.0, 0.0, 0.0);
				for(aj = 0;aj<=aaLength;aj++) {
					for(ai = 0;ai<=aaLength;ai++) {
						col += aaCol[aj*aaArrayX +ai +aOrg];
						colNum += 1.0;
					}
				}
				col /= colNum;

			}

		  /* mark pixels with debugging */
			if( glob->getDebugOut() > 0) col = ntlColor(0,1,0);

			/* store pixel */
			if(!showAAPic) {
				finalPic[(scanline-1)*picX+sx] = col; 
			}
			screenPos +=  rightStep;

		} /* foreach x */

		/* init aa array */
		if(showAAPic) {
			for(int j=0;j<=aaArrayY-1;j++) {
				for(int i=0;i<=aaArrayX-1;i++) {
					if(aaUse[j*aaArrayX +i]==1) finalPic[((scanline-1)*aaLength +j)*picX+i][0] = 1.0;
				}
			}
		}

		for(int i=0;i<aaArrayX;i++) {
			aaCol[(aaArrayY-1)*aaArrayX+i] = aaCol[0*aaArrayX+i];
			aaUse[(aaArrayY-1)*aaArrayX+i] = aaUse[0*aaArrayX+i];
		}
		for(int j=0;j<aaArrayY-1;j++) {
			for(int i=0;i<aaArrayX;i++) {
				aaCol[j*aaArrayX+i] = ntlColor(0.0, 0.0, 0.0);
				aaUse[j*aaArrayX+i] = 0;
			}
		}

	} /* foreach y */
	rendEnd = getTime();


	/* write png file */
	{
		int w = picX;
		int h = picY;

		unsigned rowbytes = w*4;
		unsigned char *screenbuf, **rows;
		screenbuf = (unsigned char*)malloc( h*rowbytes );
		rows = (unsigned char**)malloc( h*sizeof(unsigned char*) );
		unsigned char *filler = screenbuf;

		// cutoff color values 0..1
		for(int j=0;j<h;j++) {
			for(int i=0;i<w;i++) {
				ntlColor col = finalPic[j*w+i];
				for (unsigned int cc=0; cc<3; cc++) {
					if(col[cc] <= 0.0) col[cc] = 0.0;
					if(col[cc] >= 1.0) col[cc] = 1.0;
				}
				*filler = (unsigned char)( col[0]*255.0 ); 
				filler++;
				*filler = (unsigned char)( col[1]*255.0 ); 
				filler++;
				*filler = (unsigned char)( col[2]*255.0 ); 
				filler++;
				*filler = (unsigned char)( 255.0 ); 
				filler++; // alpha channel
			}
		}

		for(int i = 0; i < h; i++) rows[i] = &screenbuf[ (h - i - 1)*rowbytes ];
		writePng(outfn_conv.str().c_str(), rows, w, h);
	}


	// next frame 
	glob->setAniCount( glob->getAniCount() +1 );

	// done 
	timeEnd = getTime();

	char resout[1024];
	snprintf(resout,1024, "NTL Done %s, frame %d/%d (took %s scene, %s raytracing, %s total, %d shades, %d i.s.'s)!\n", 
				 outfn_conv.str().c_str(), (glob->getAniCount()), (glob->getAniFrames()+1),
				 getTimeString(totalStart-timeStart).c_str(), getTimeString(rendEnd-rendStart).c_str(), getTimeString(timeEnd-timeStart).c_str(),
				 glob->getCounterShades(),
				 glob->getCounterSceneInter() );
	debMsgStd("ntlWorld::renderScene",DM_MSG, resout, 1 );

	/* clean stuff up */
	delete [] aaCol;
	delete [] aaUse;
	delete [] finalPic;
	glob->getRenderScene()->cleanupScene();

	if(mpGlob->getSingleFrameMode() ) {
		debMsgStd("ntlWorld::renderScene",DM_NOTIFY, "Single frame mode done...", 1 );
		return 1;
	}
#endif // ELBEEM_PLUGIN
	return 0;
}