コード例 #1
0
ファイル: draw13.cpp プロジェクト: bradhugh/mame
void quad_setup_data::compute(const render_primitive &prim, const int prescale)
{
	const render_quad_texuv *texcoords = &prim.texcoords;
	int texwidth = prim.texture.width;
	int texheight = prim.texture.height;
	float fdudx, fdvdx, fdudy, fdvdy;
	float width, height;
	float fscale;
	/* determine U/V deltas */
	if ((PRIMFLAG_GET_SCREENTEX(prim.flags)))
		fscale = (float) prescale;
	else
		fscale = 1.0f;

	fdudx = (texcoords->tr.u - texcoords->tl.u); // a a11
	fdvdx = (texcoords->tr.v - texcoords->tl.v); // c a21
	fdudy = (texcoords->bl.u - texcoords->tl.u); // b a12
	fdvdy = (texcoords->bl.v - texcoords->tl.v); // d a22

	width = fabsf(( fdudx * (float) (texwidth) + fdvdx * (float) (texheight)) ) * fscale;
	height = fabsf((fdudy * (float) (texwidth) + fdvdy * (float) (texheight)) ) * fscale;

	fdudx = signf(fdudx) / fscale;
	fdvdy = signf(fdvdy) / fscale;
	fdvdx = signf(fdvdx) / fscale;
	fdudy = signf(fdudy) / fscale;

#if 0
	printf("tl.u %f tl.v %f\n", texcoords->tl.u, texcoords->tl.v);
	printf("tr.u %f tr.v %f\n", texcoords->tr.u, texcoords->tr.v);
	printf("bl.u %f bl.v %f\n", texcoords->bl.u, texcoords->bl.v);
	printf("br.u %f br.v %f\n", texcoords->br.u, texcoords->br.v);
	/* compute start and delta U,V coordinates now */
#endif

	dudx = round_nearest(65536.0f * fdudx);
	dvdx = round_nearest(65536.0f * fdvdx);
	dudy = round_nearest(65536.0f * fdudy);
	dvdy = round_nearest(65536.0f * fdvdy);
	startu = round_nearest(65536.0f * (float) texwidth * texcoords->tl.u);
	startv = round_nearest(65536.0f * (float) texheight * texcoords->tl.v);

	/* clamp to integers */

	rotwidth = round_nearest(width);
	rotheight = round_nearest(height);

	//printf("%d %d rot %d %d\n", texwidth, texheight, rotwidth, rotheight);

	startu += (dudx + dudy) / 2;
	startv += (dvdx + dvdy) / 2;

}
コード例 #2
0
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)

{
    label = new QLabel("0", this);
    label -> setGeometry(QRect(QPoint(50,70),QSize(250,50)));
    label->setStyleSheet("background-color: rgb(221,160,221); font: bold 14px;");
    label->setAlignment(Qt::AlignCenter);



    for(int i =0; i<10; i++){
        QString operations[] = {"C","=","+","-","*","/","^","root","sqrt","+-"};
        operationButton[i] = new QPushButton(operations[i],this);

        if(i == 1){
          connect(operationButton[i],SIGNAL(released()),this, SLOT(equals()));
        }
        else if(i == 9){
            connect(operationButton[i],SIGNAL(released()),this, SLOT(signf()));
        }
        else{
        connect(operationButton[i],SIGNAL(released()),this, SLOT(operationPushed()));
            }
        }

    for(int i =0; i<10; i++){
        QString digit = QString::number(i);
        buttons[i] = new QPushButton(digit,this);
        connect(buttons[i],SIGNAL(released()),this, SLOT(buttonPushed()));
    }
    setGeo();

}
コード例 #3
0
ファイル: dge_math.cpp プロジェクト: jacquesh/dge
float slideAngle(float from, float to, float maxDistance)
{
    float offset = to - from;
    float topEndWrapOffset = (to + TWOPI) - from;
    float bottomEndWrapOffset = (to - TWOPI) - from;
    if(fabsf(offset) > fabsf(topEndWrapOffset))
    {
        offset = topEndWrapOffset;
    }
    else if(fabsf(offset) > fabsf(bottomEndWrapOffset))
    {
        offset = bottomEndWrapOffset;
    }
    float direction = signf(offset);

    float result;
    if(fabsf(offset) < maxDistance)
    {
        result = to;
    }
    else
    {
        result = from + direction*maxDistance;
    }

    return result;
}
コード例 #4
0
ファイル: DBOXMath.cpp プロジェクト: ongamex/old_stuff
bool OverlapfRect(fRect* r1, fRect* r2, D3DXVECTOR3* o)
{
	
	float xC1 = (r1->right + r1->left)/2.f;
	float yC1 = (r1->bottom + r1->top)/2.f;

	float xR1 = (r1->right - r1->left)/2.f;
	float yR1 = (r1->bottom - r1->top)/2.f;

	float xC2 = (r2->right + r2->left)/2.f;
	float yC2 = (r2->bottom + r2->top)/2.f;

	float xR2 = (r2->right - r2->left)/2.f;
	float yR2 = (r2->bottom - r2->top)/2.f;

	float px = xR1+xR2 - fabsf(xC1 - xC2);
	float py = yR1+yR2 - fabsf(yC1 - yC2);

	bool Intersect = (px >= 0 && py >= 0);

	if(Intersect){
		D3DXVECTOR3 vc1(xC1, yC1, 0);
		D3DXVECTOR3 vc2(xC2, yC2, 0);
		D3DXVECTOR3 Dir = vc1 - vc2;
		D3DXVec3Normalize(&Dir, &Dir);
		
		if(py < px)
		{
			Dir = D3DXVECTOR3(0, signf(Dir.y)*py, 0);
		}
		else
		{
			Dir = D3DXVECTOR3(signf(Dir.x)*px , 0 , 0);
		}

		*o = Dir;

		return true;
	}
	
	*o = D3DXVECTOR3(0,0,0);
	return false;
}
コード例 #5
0
ファイル: dge_math.cpp プロジェクト: jacquesh/LostLuggage
float dge::slide(float from, float to, float maxDistance)
{
    float offset = to - from;
    float direction = signf(offset);

    float result;
    if(fabsf(offset) < maxDistance)
    {
        result = to;
    }
    else
    {
        result = from + direction*maxDistance;
    }

    return result;
}
コード例 #6
0
ファイル: sign.c プロジェクト: razzlefratz/MotleyTools
int main (int argc, char const * argv [])

{
	static char const * optv [] =
	{
		"print a simple sign on stdout",
		PUTOPTV_S_DIVINE,
		"c:w:",
		"c c\tfill character is c [\'c\']",
		"w n\tpage width is n [78]",
		(char const *) (0)
	};
	char o = '#';
	size_t width = 78;
	signed c;
	while (~ (c = getoptv (argc, argv, optv)))
	{
		switch (c)
		{
		case 'c':
			o = * optarg;
			break;
		case 'w':
			width = uintspec (optarg, 1, UCHAR_MAX);
			break;
		default: 
			break;
		}
	}
	argc -= optind;
	argv += optind;
	while ((argc) && (* argv))
	{
		signf (* argv, o, width);
		argc--;
		argv++;
	}
	exit (0);
}
コード例 #7
0
ファイル: MouseHandler.cpp プロジェクト: AlexDiede/spring
void CMouseHandler::MouseRelease(int x, int y, int button)
{
	if (button > NUM_BUTTONS)
		return;

	camHandler->GetCurrentController().MouseRelease(x, y, button);

	dir = hide ? camera->forward : camera->CalcPixelDir(x, y);
	buttons[button].pressed = false;

	if (inMapDrawer && inMapDrawer->IsDrawMode()){
		inMapDrawer->MouseRelease(x, y, button);
		return;
	}

	if (activeReceiver) {
		activeReceiver->MouseRelease(x, y, button);
		if(!buttons[SDL_BUTTON_LEFT].pressed && !buttons[SDL_BUTTON_MIDDLE].pressed && !buttons[SDL_BUTTON_RIGHT].pressed)
			activeReceiver = NULL;
		return;
	}

	GML_RECMUTEX_LOCK(sel); //FIXME redundant? (selectedUnits already has mutexes)

	// Switch camera mode on a middle click that wasn't a middle mouse drag scroll.
	// the latter is determined by the time the mouse was held down:
	// switch (dragScrollThreshold)
	//   <= means a camera mode switch
	//    > means a drag scroll
	if (button == SDL_BUTTON_MIDDLE) {
		if (buttons[SDL_BUTTON_MIDDLE].time > (gu->gameTime - dragScrollThreshold))
			ToggleMiddleClickScroll();
		return;
	}

	if (gu->fpsMode) {
		return;
	}

	if ((button == SDL_BUTTON_LEFT) && !buttons[button].chorded) {
		ButtonPressEvt& bp = buttons[SDL_BUTTON_LEFT];

		if (!keyInput->IsKeyPressed(SDLK_LSHIFT) && !keyInput->IsKeyPressed(SDLK_LCTRL)) {
			selectedUnits.ClearSelected();
		}

		if (bp.movement > 4) {
			// select box
			float2 topright, btmleft;
			GetSelectionBoxCoeff(bp.camPos, bp.dir, camera->pos, dir, topright, btmleft);

			// GetSelectionBoxCoeff returns us the corner pos, but we want to do a inview frustum check.
			// To do so we need the frustum planes (= plane normal + plane offset).
			float3 norm1 = camera->up;
			float3 norm2 = -camera->up;
			float3 norm3 = camera->right;
			float3 norm4 = -camera->right;

			#define signf(x) ((x>0.0f) ? 1.0f : -1)
			if (topright.y != 0) norm1 = (camera->forward * signf(-topright.y)) + (camera->up / math::fabs(topright.y));
			if (btmleft.y  != 0) norm2 = (camera->forward * signf(  btmleft.y)) - (camera->up / math::fabs(btmleft.y));
			if (topright.x != 0) norm3 = (camera->forward * signf(-topright.x)) + (camera->right / math::fabs(topright.x));
			if (btmleft.x  != 0) norm4 = (camera->forward * signf(  btmleft.x)) - (camera->right / math::fabs(btmleft.x));

			const float4 plane1(norm1, -(norm1.dot(camera->pos)));
			const float4 plane2(norm2, -(norm2.dot(camera->pos)));
			const float4 plane3(norm3, -(norm3.dot(camera->pos)));
			const float4 plane4(norm4, -(norm4.dot(camera->pos)));

			selectedUnits.HandleUnitBoxSelection(plane1, plane2, plane3, plane4);
		} else {
			CUnit* unit;
			CFeature* feature;
			TraceRay::GuiTraceRay(camera->pos, dir, globalRendering->viewRange * 1.4f, NULL, unit, feature, false);

			selectedUnits.HandleSingleUnitClickSelection(unit, true);
		}

		bp.lastRelease = gu->gameTime;
	}
}
コード例 #8
0
ファイル: MouseHandler.cpp プロジェクト: nixtux/spring
void CMouseHandler::MouseRelease(int x, int y, int button)
{
	const CUnit *_lastClicked = lastClicked;
	lastClicked = nullptr;

	if (button > NUM_BUTTONS)
		return;

	dir = hide ? camera->GetDir() : camera->CalcPixelDir(x, y);

	buttons[button].pressed = false;

	if (inMapDrawer && inMapDrawer->IsDrawMode()){
		inMapDrawer->MouseRelease(x, y, button);
		return;
	}

	if (activeReceiver != nullptr) {
		activeReceiver->MouseRelease(x, y, button);

		if (!buttons[SDL_BUTTON_LEFT].pressed && !buttons[SDL_BUTTON_MIDDLE].pressed && !buttons[SDL_BUTTON_RIGHT].pressed)
			activeReceiver = nullptr;

		return;
	}

	// Switch camera mode on a middle click that wasn't a middle mouse drag scroll.
	// the latter is determined by the time the mouse was held down:
	// switch (dragScrollThreshold)
	//   <= means a camera mode switch
	//    > means a drag scroll
	if (button == SDL_BUTTON_MIDDLE) {
		if (buttons[SDL_BUTTON_MIDDLE].time > (gu->gameTime - dragScrollThreshold))
			ToggleMiddleClickScroll();
		return;
	}

	if (gu->fpsMode)
		return;
	// outside game, neither guiHandler nor quadField exist and TraceRay would crash
	if (guihandler == nullptr)
		return;

	if ((button == SDL_BUTTON_LEFT) && !buttons[button].chorded) {
		ButtonPressEvt& bp = buttons[SDL_BUTTON_LEFT];

		if (!KeyInput::GetKeyModState(KMOD_SHIFT) && !KeyInput::GetKeyModState(KMOD_CTRL))
			selectedUnitsHandler.ClearSelected();

		if (bp.movement > 4) {
			// select box
			float2 topright, btmleft;
			GetSelectionBoxCoeff(bp.camPos, bp.dir, camera->GetPos(), dir, topright, btmleft);

			// GetSelectionBoxCoeff returns us the corner pos, but we want to do a inview frustum check.
			// To do so we need the frustum planes (= plane normal + plane offset).
			float3 norm1 = camera->GetUp();
			float3 norm2 = -camera->GetUp();
			float3 norm3 = camera->GetRight();
			float3 norm4 = -camera->GetRight();

			#define signf(x) ((x>0.0f) ? 1.0f : -1)
			if (topright.y != 0) norm1 = (camera->GetDir() * signf(-topright.y)) + (camera->GetUp() / math::fabs(topright.y));
			if (btmleft.y  != 0) norm2 = (camera->GetDir() * signf(  btmleft.y)) - (camera->GetUp() / math::fabs(btmleft.y));
			if (topright.x != 0) norm3 = (camera->GetDir() * signf(-topright.x)) + (camera->GetRight() / math::fabs(topright.x));
			if (btmleft.x  != 0) norm4 = (camera->GetDir() * signf(  btmleft.x)) - (camera->GetRight() / math::fabs(btmleft.x));

			const float4 plane1(norm1, -(norm1.dot(camera->GetPos())));
			const float4 plane2(norm2, -(norm2.dot(camera->GetPos())));
			const float4 plane3(norm3, -(norm3.dot(camera->GetPos())));
			const float4 plane4(norm4, -(norm4.dot(camera->GetPos())));

			selectedUnitsHandler.HandleUnitBoxSelection(plane1, plane2, plane3, plane4);
		} else {
			const CUnit* unit = nullptr;
			const CFeature* feature = nullptr;

			TraceRay::GuiTraceRay(camera->GetPos(), dir, globalRendering->viewRange * 1.4f, NULL, unit, feature, false);
			lastClicked = unit;

			const bool selectType = (bp.lastRelease >= (gu->gameTime - doubleClickTime) && unit == _lastClicked);

			selectedUnitsHandler.HandleSingleUnitClickSelection(const_cast<CUnit*>(unit), true, selectType);
		}

		bp.lastRelease = gu->gameTime;
	}
}
コード例 #9
0
ファイル: kick.C プロジェクト: edymanoloiu/FotbalRobotic
/* returns 1 if a kick actually done */
int smart_kick_hard_abs(float abs_dir, KickMode mode, float targ_vel,
			TurnDir rot)
{
  TurnKickCommand HKCommand;
  HKCommand.time = -1;
  HKCommand.turn_neck = FALSE;
  
  DebugKick(printf("\nsmart_kick_hard: Time: %d\n", Mem->CurrentTime.t));

  LogAction5(50, "smart_kick_hard_abs: mode = %d, angle = %.1f, targ_vel %.4f ",
	     mode, abs_dir, targ_vel);

  if (!Mem->BallPositionValid()) {
    my_error("smart_kick_hard called with ball position not valid");
    return 0;
  }

  if (!Mem->BallKickable()) {
    my_error("smart_kick_hard called with ball not kickable!");
    return 0;
  }
  
  /* if the velocity isn's valid, turn to face ball */

  if ( !Mem->BallVelocityValid() ) {
    float ball_ang_from_body = Mem->BallAngleFromBody(); /* for efficiency */
    LogAction2(60, "smart_kick_hard_abs: turning to face ball");
    DebugKick2(printf("smart_kcik_hard: turning to face ball\n"));
    if (Mem->CanSeeBallWithNeck()) {
      if (Mem->PlayMode == PM_Play_On ||
	  (Mem->PlayMode == PM_My_Goal_Kick && Mem->LastAction->type == CMD_kick)) {
	LogAction2(70, "smart_kick_hard_abs: turning neck and stopping ball");
	HKCommand.time = Mem->CurrentTime;
	HKCommand.type = CMD_kick;
	HKCommand.angle = ball_ang_from_body + 180;
	HKCommand.power = Mem->CP_stop_ball_power;
	
	HKCommand.turn_neck = TRUE;
	HKCommand.turn_neck_angle = Mem->LimitTurnNeckAngle(Mem->BallAngleFromNeck());
      } else {
	LogAction2(70, "smart_kick_hard_abs: just turniong neck");
	HKCommand.time = Mem->CurrentTime;
	HKCommand.type = CMD_none;
	HKCommand.angle = 0;
	HKCommand.power = 0;
	
	HKCommand.turn_neck = TRUE;
	HKCommand.turn_neck_angle = Mem->LimitTurnNeckAngle(Mem->BallAngleFromNeck());
      }
    } else {
      /* turn body to face ball, and turn neck to straight ahead */
      LogAction2(70, "smart_kick_hard_abs: turning neck and body");
      HKCommand.time = Mem->CurrentTime;
      HKCommand.type = CMD_turn;
	HKCommand.turn_neck = TRUE;
      if (fabs(ball_ang_from_body) > Mem->MaxEffectiveTurn()) {
	/* out body can't get to where we want to go */
	HKCommand.angle = 180; /* get our maximum effective turn */
	HKCommand.turn_neck_angle = ball_ang_from_body -
	  signf(ball_ang_from_body)*Mem->MaxEffectiveTurn();
      } else {
	HKCommand.angle = ball_ang_from_body;
	HKCommand.turn_neck_angle = -Mem->MyNeckRelAng();
      }
    }
    return DoTurnKickCommand(HKCommand);
  } 

  LogAction2(210, "HardestKick: got past vel check");
  rot = KickRotationDirectionAbs(abs_dir, rot);
  LogAction2(210, "HardestKick: got past rot setting");

#ifdef NEVER
  /* With the new kick code, the ball goes through the player, 
     so we don't usually need to do a turn-ball as part of a shot */
  if (mode <= KM_Moderate &&
      Mem->IsPointBehind(Mem->BallAbsolutePosition(), abs_dir)) {
    /* see if we need to rotate one way */
    DebugKick(cout << "smart_kick_hard: decign if rotating " << rot << endl);
    /* now decide if ball is on the wrong side	 */
    if (Mem->IsPointBehind(Mem->BallAbsolutePosition(), abs_dir+((int)rot)*90)) {
      /* start rotating right way */
      DebugKick(cout << "smart_kick_hard: special turnball to avoid opp" << endl);
      TurnKickCommand com;
      KickToRes res = turnball_kick( abs_dir - Mem->MyAng(),
				     //abs_dir + ((int)rot)*90 - Mem->MyAng(),
				     rot, FALSE, &com);
      if (res == KT_DidNothing || res == KT_LostBall)
	my_error("smart_kick_hard: special turnball; turnkick failed, res: %d", res);
      else
	return DoTurnKickCommand(com);
    }
  }
#endif  
  
  
  switch (mode) {
  case KM_None:
    my_error("KM_None is not a valid kick mode for smart_kick_hard!");
    break;
    
    // HKStep meanings: 0 turning player, 1 moving ball, 2 using moderate
  case KM_HardestKick: {      
    if (Mem->CurrentTime - 1 != Mem->HKTime) {
      DebugKick(printf("First in a chain of calls\n"));
      LogAction2(210, "HardestKick: Setting up for first call");
      /* this is the first in a chain of calls */      
      Mem->HKStep = 0;
      /* decide which way to rotate ball */
      Mem->HKrot = rot;
      /*AngleDeg ang = Mem->BallAngle() + Mem->MyAng() - abs_dir;
      NormalizeAngleDeg(&ang);
      if (ang >= 0)
	Mem->HKrot = TURN_CW;
      else
	Mem->HKrot = TURN_CCW;*/
    } else {
      LogAction4(210, "HardestKick: Setting new step %d (old %d)", Mem->HKStepNext, Mem->HKStep);
      Mem->HKStep = Mem->HKStepNext;
    }
  

    if (Mem->HKStep == 0) {
      /* see if we need to turn */
      LogAction2(210, "HardestKick: processing for step 0");
      AngleDeg target_dir = abs_dir - Mem->MyBodyAng() + 
	((int)Mem->HKrot)*Mem->CP_hardest_kick_player_ang;
      NormalizeAngleDeg(&target_dir);
      LogAction2(210, "HardestKick: (0) norm angle");
      if (fabs(target_dir) > Mem->CP_max_hard_kick_angle_err) {
	LogAction2(210, "HardestKick: (0) need to turn!");
	LogAction3(210, "HardestKick: (0) BallVelValid: %f", Mem->BallVelocityValid());
	LogAction4(210, "HardestKick: (0) speed %f, %f!", 
		   Mem->BallSpeed(), Mem->CP_hard_kick_dist_buffer);
	LogAction3(210, "HardestKick: (0) will be kick %d", 
		   Mem->BallWillBeKickable(1,0,Mem->CP_hard_kick_dist_buffer));
	if (!Mem->BallWillBeKickable(1, 0, Mem->CP_hard_kick_dist_buffer) &&
	    Mem->BallVelocityValid() && 
	    Mem->BallSpeed() > Mem->CP_hard_kick_dist_buffer) {
	  LogAction2(70, "smart_kick_hard_abs: would turn for power, but must stop ball");
	  if (Mem->BallVelocityValid()) {
	    LogAction2(70, "smart_kick_hard_abs: would turn for power, but stopping ball");
	    HKCommand = dokick(-180, 0, 1.0);
	    if (HKCommand.time == -1) {
	      my_error("Stopping ball for dokick failed!");
	    }
	  } else {
	    LogAction2(70, "smart_kick_hard_abs: would turn for power, but stopping unknown vel ball");
	    HKCommand.time = Mem->CurrentTime;
	    HKCommand.type = CMD_kick;
	    HKCommand.angle = Mem->BallAngleFromBody() + 180;
	    HKCommand.power = Mem->CP_stop_ball_power;

	    HKCommand.turn_neck = TRUE;
	    HKCommand.turn_neck_angle = Mem->LimitTurnNeckAngle(Mem->BallAngleFromNeck());
	  }
	  //Mem->HKTime = Mem->CurrentTime;
	  LogAction2(210, "HardestKick: (0) setting step next to 0");
	  Mem->HKStepNext = 0; //stay in turn, we'll drop through next times
	} else {
	  LogAction4(70, "smart_kick_hard_abs: hardest turning for power %f %d", 
		     target_dir, Mem->CP_max_hard_kick_angle_err);
	  DebugKick(printf("turning to get hard kick\n"));
	  //Mem->HKTime = Mem->CurrentTime;
	  Mem->HKStepNext = 0; //stay in turn, we'll drop through next times
	  HKCommand.type = CMD_turn;
	  HKCommand.angle = target_dir;
	  HKCommand.time = Mem->CurrentTime;
	  HKCommand.turn_neck = FALSE;
	  //break; //used to be: return DoTurnKickCommand(HKCommand);
	}
      }
    }

    LogAction2(210, "HardestKick: after 0 processing");
    
    /* AngleDeg turn_target = abs_dir + 180 +
      ((int)Mem->HKrot)*Mem->CP_hardest_kick_angle_disp; */
    AngleDeg turn_target = abs_dir + 
      ((int)Mem->HKrot)*(Mem->CP_hardest_kick_ball_ang);
    NormalizeAngleDeg(&turn_target);
    AngleDeg targ_err = turn_target-Mem->MyBodyAng()-Mem->BallAngleFromBody();
    NormalizeAngleDeg(&targ_err);
    if ( (Mem->HKStep == 1 ||
	  (Mem->HKStep < 1 && HKCommand.time != Mem->CurrentTime)) &&
	 fabs(targ_err) > Mem->CP_KickTo_err) {
      /* on step 1, we turn ball to back of us */      
      LogAction4(70, "smart_kick_hard_abs: hardest turning ball backwards %f %f", 
		 turn_target, targ_err);
      HKCommand = hard_kick_turnball(turn_target, TURN_CLOSEST, TRUE);//TRUE to stop ball
      if (HKCommand.time != Mem->CurrentTime) {
	LogAction2(70, "kick_hardest: turnball won't work, so stopping ball");
	HKCommand = dokick(-180, 0, 1.0);
      }
      Mem->HKStepNext = 1;
    }
    LogAction2(210, "HardestKick: after 1 processing");
    if (Mem->HKStep == 2 ||
	(Mem->HKStep < 2 && HKCommand.time != Mem->CurrentTime)) {
      /* on step 2, we call the moderate code */
      /* or if step 0 had turnball problems, we'll go ahead and drop
	 to this code */
      LogAction2(70, "smart_kick_hard_abs: calling kick_hard_moderate");
      HKCommand = kick_hard_moderate(abs_dir, targ_vel, rot);
      Mem->HKStepNext = 2;
    }
    LogAction2(210, "HardestKick: after 2 processing");
    if (Mem->HKStep < 0 && Mem->HKStep > 2)
      my_error("HKstep is not in a valid state: %d", Mem->HKStep);
    
    Mem->HKTime = Mem->CurrentTime;
    LogAction2(210, "HardestKick: after all processing");
    break; //used to be: return DoTurnKickCommand(HKCommand);
  }
  
  case KM_Hard:
    /* Actually, this is implemented as a "dash helping kick" at a higher level 
       in behave */
    my_error("KM_Hard not implemented yet!");
    //dump_core("blah");
    break;

  case KM_ModerateWTurn: {
    /* This mode is *not* garunteed to be harder than moderate
       It's really intended for dead ball situations */
    AngleDeg target_dir = abs_dir - Mem->MyBodyAng() + rot*Mem->CP_hardest_kick_player_ang;
    NormalizeAngleDeg(&target_dir);
    LogAction3(70, "ModerateWTurn: norm angle %.2f", target_dir);
    if (fabs(target_dir) > Mem->CP_max_hard_kick_angle_err) {
      LogAction2(70, "ModerateWTurn: (0) need to turn!");
      if (Mem->BallWillBeKickable()) {
	HKCommand.type = CMD_turn;
	HKCommand.angle = target_dir;
	HKCommand.time = Mem->CurrentTime;
	HKCommand.turn_neck = FALSE;
	break;
      } else {
	LogAction2(70, "ModerateWTurn: need to turn, but ball won't be kickable, so call moderate");
      }
    }
    HKCommand = kick_hard_moderate(abs_dir, targ_vel, rot);
  } break;
    
  case KM_Moderate:
    HKCommand = kick_hard_moderate(abs_dir, targ_vel, rot);
    break;
    
  case KM_Quickly:
  case KM_QuickestRelease: {
      Mem->HKStep = Mem->HKStepNext = -1;
      /* see if the hardest kick in the direction we want will be collision */
      /* use our dokick function to correct for vel */
      TurnKickCommand kickCom;
      Vector vPredBall;
      Bool   CanKickToTraj;
      if (!is_hard_kick_coll(abs_dir, &kickCom, &vPredBall, targ_vel, &CanKickToTraj)) {
	/* there is no collsion! */
	if (mode == KM_Quickly &&
	    Mem->BallWillBeKickable() &&
	    fabs(Mem->BallAngleFromBody()) > Mem->CP_max_hard_kick_angle_err) {
	  /* In KM_Quickly mode, we can turn to ball and get it next time */
	  LogAction2(70, "smart_kick_hard_abs: km_quickly: turning for power");
	  HKCommand.time = Mem->CurrentTime;
	  HKCommand.type = CMD_turn;
	  HKCommand.angle = Mem->AngleToFromBody(Mem->BallPredictedPosition());
	} else
	  HKCommand = kickCom;
	break; //used to be:return DoTurnKickCommand(HKCommand);
      } else {
	/* do turnball */
	if (!CanKickToTraj) {
	  /* can't kick to trajectory, so just do the collision kick */
	  LogAction2(70, "smart_kick_hard_abs: km_quick: can't kick to traj, taking the collision");
	  HKCommand = kickCom;
	} else {
	  LogAction2(70, "smart_kick_hard_abs: km_quick: turnball");
	  HKCommand = hard_kick_turnball(abs_dir, rot);
	  if (HKCommand.time != Mem->CurrentTime) {
	    LogAction2(70, "km_quick: I'm using the original kick commands, even though it's a collision");
	    HKCommand = kickCom;
	  }
	}
	break; //used to be:return DoTurnKickCommand(hard_kick_turnball(abs_dir, rot));
      }
    
    }
    my_error("How did I get to end of KM_Quickly/KM_Quickest_Release");
    break;
    
  default:
    my_error("Invalid/Unimplemented kick mode passed to smart_kick_hard");
    break;
  }

  /* now we'll add a turn_neck into this to look at where the ball will be
     If a turn_neck is already there, we won't do this */
  LogAction2(210, "KickHard: checking for turn_neck");
  if (!HKCommand.turn_neck) {
    if (HKCommand.time != Mem->CurrentTime)
      my_error("Adding a turn_neck to an invalid HKCommand");
    LogAction2(70, "smart_kick_hard_abs: doing a turn_neck");
    Vector pred_ball_pos;
    if (HKCommand.type == CMD_kick)
      pred_ball_pos = Mem->BallPredictedPosition(1, HKCommand.power, HKCommand.angle);
    else
      pred_ball_pos = Mem->BallPredictedPosition(1);
    float pred_ball_dir = (pred_ball_pos - Mem->MyPredictedPosition()).dir();
    pred_ball_dir -= Mem->MyNeckGlobalAng();
    pred_ball_dir -= (HKCommand.type == CMD_turn ? HKCommand.angle : 0);

    HKCommand.turn_neck = TRUE;
    HKCommand.turn_neck_angle = Mem->LimitTurnNeckAngle(GetNormalizeAngleDeg(pred_ball_dir));
  }
  
  LogAction2(210, "KickHard: returning");
  return DoTurnKickCommand(HKCommand);
}
コード例 #10
0
ファイル: kick.C プロジェクト: edymanoloiu/FotbalRobotic
/* we always reason about the right trajectory for the ball leave velocity
   correction for dokick */
KickToRes turnball_kick(AngleDeg target_dir, TurnDir rotate, 
		  Bool StopBall, TurnKickCommand* pCom,
		  float EndDist, float closeMarg, float kickFac)
{
  float dir;
  float dist;
  Vector btraj;

  pCom->time = -1;
  pCom->turn_neck = FALSE;
  
  DebugKick(printf("\nat turnball_kick: target_dir: %f\n", target_dir));
  LogAction4(60, "Turnball_kick: targ_dir: %.1f  dir: %d", target_dir, (int)rotate);
  
  NormalizeAngleDeg(&target_dir);
  
  //DebugKick(printf("HERE Time: %d\n", Mem->CurrentTime.t));
  /* the pos valid is not really right - if we are turning the ball and didn't
     actually see it last time, then there's a problem */
  if ( !Mem->BallPositionValid() || !Mem->BallKickable() ) {
    LogAction2(90, "turnball_kick: lost the ball");
    return KT_LostBall;
  }

  /* if the velocity isn's valid, turn to face ball */
  if ( !Mem->BallVelocityValid() ) {
    float ball_ang_from_body = Mem->BallAngleFromBody(); /* for efficiency */
    LogAction2(90, "turnball_kick: vel is not valid, looking at it");
    DebugKick(printf("turning to face ball\n"));
    if (Mem->CanSeeBallWithNeck()) {
      pCom->time = Mem->CurrentTime;
      pCom->type = CMD_kick;
      pCom->angle = ball_ang_from_body + 180;
      pCom->power = Mem->CP_stop_ball_power;

      pCom->turn_neck = TRUE;
      pCom->turn_neck_angle = Mem->LimitTurnNeckAngle(Mem->BallAngleFromNeck());
    } else {
      /* turn body to face ball, and turn neck to straight ahead */
      pCom->time = Mem->CurrentTime;
      pCom->type = CMD_turn;
	pCom->turn_neck = TRUE;
      if (fabs(ball_ang_from_body) > Mem->MaxEffectiveTurn()) {
	/* out body can't get to where we want to go */
	pCom->angle = 180; /* get our maximum effective turn */
	pCom->turn_neck_angle = ball_ang_from_body -
	  signf(ball_ang_from_body)*Mem->MaxEffectiveTurn();
      } else {
	pCom->angle = ball_ang_from_body;
	pCom->turn_neck_angle = -Mem->MyNeckRelAng();
      }
      
    }
    
    return KT_TurnedToBall;
  } 
  
  DebugKick(printf(" ball.dist: %f\t.dir: %f\n",
	 Mem->BallDistance(), Mem->BallAngle()));
  DebugKick(printf(" HERE ball.vel.x: %f\t.y: %f\tmod: %f\n",
	 Mem->BallRelativeVelocity().x, Mem->BallRelativeVelocity().y,
	 Mem->BallSpeed()));
  DebugKick(printf(" ball.rpos.x: %f\t.y: %f\n",
	 Mem->BallRelativePosition().x, Mem->BallRelativePosition().y));
  DebugKick(printf(" target_dir: %f\n", target_dir));

  if ( fabs(GetNormalizeAngleDeg(target_dir - Mem->BallAngleFromBody())) < Mem->CP_KickTo_err) {
    /* Do something to indicate we are done */
    if (!StopBall || Mem->BallSpeed() < Mem->CP_max_ignore_vel)
      return KT_DidNothing;
    LogAction2(90, "turnball_kick: we're there, stopping the ball");
    DebugKick(printf("  Stop ball kick\n"));
    dir = 0;
    dist = 0;    
    PlayerMovementCorrection(&dir, &dist);
    *pCom = dokick(dir, dist, 1.0);
    pCom->turn_neck = FALSE;
    return KT_Success;
  }

  if (rotate == TURN_AVOID) {
    rotate = RotToAvoidOpponent(target_dir + Mem->MyBodyAng());
  }
  
  if (rotate == TURN_CLOSEST) {
    rotate = RotClosest(target_dir + Mem->MyBodyAng());
  }
  
  
  if (is_straight_kick(target_dir, EndDist, closeMarg)) {
    float pow;
      
    btraj = Polar2Vector(EndDist, target_dir) - Mem->BallRelativeToBodyPosition();
    dir = btraj.dir();
    dist = btraj.mod();
    
    /* now we're goign to do some distance twiddling to get the ball to
       get to the right angle and stop */
    pow = dist / Mem->BallKickRate();
    pow = Min(pow, Mem->CP_max_turn_kick_pow);
    dist = pow * Mem->BallKickRate();
      
    LogAction4(90, "turnball_kick: striaght kick: dist %f at %f", dist, dir);
    DebugKick(printf("  Straight kick# dir: %f dist: %f\n", dir, dist));
    PlayerMovementCorrection(&dir, &dist);
    *pCom = dokick(dir, dist, 1.0);
    pCom->turn_neck = FALSE;

  } else if (Mem->BallDistance() < closeMarg) {

    /* ball is too close to do a tangent kick, so do a kick at 90 degrees */
    dir = ((int)rotate)*(-90) + Mem->BallAngleFromBody();
    dist = 2.0*sqrt(Sqr(Mem->CP_opt_ctrl_dist) - Sqr(Mem->BallDistance()));
    LogAction2(90, "turnball_kick: 90 deg kick");
    DebugKick(printf("  Close kick# dir: %f dist: %f\n", dir, dist));
    PlayerMovementCorrection(&dir, &dist);
    *pCom = dokick(dir, dist, kickFac);
    pCom->turn_neck = FALSE;

  } else {

    /* do a turning kick */
    /* we make a circle around the player of radius closeMarg
       and calculate the trajectory that goes in the right direction and is
       tangent to the circle */
    dir = 180 + Mem->BallAngleFromBody() + ((int)rotate)*ASin(closeMarg / Mem->BallDistance());
    DebugKick(printf(" ball dist: %f\tclosest_margin: %f\n",
	   Mem->BallDistance(), closeMarg));
    dist = sqrt(Sqr(Mem->BallDistance()) - Sqr(closeMarg));
    dist +=
      sqrt(Sqr(Mem->CP_opt_ctrl_dist) - Sqr(closeMarg));
    DebugKick(printf("  Turning ball# dir: %f dist: %f\n", dir, dist));
    LogAction2(90, "turnball_kick: turning kick");
    PlayerMovementCorrection(&dir, &dist);
    *pCom = dokick(dir, dist, kickFac);
    pCom->turn_neck = FALSE;

  }

  return KT_DidKick;
}
コード例 #11
0
void init_tex_mapping(TexMapping *texmap)
{
	float smat[4][4], rmat[4][4], tmat[4][4], proj[4][4], size[3];

	if (texmap->projx == PROJ_X && texmap->projy == PROJ_Y && texmap->projz == PROJ_Z &&
	    is_zero_v3(texmap->loc) && is_zero_v3(texmap->rot) && is_one_v3(texmap->size))
	{
		unit_m4(texmap->mat);

		texmap->flag |= TEXMAP_UNIT_MATRIX;
	}
	else {
		/* axis projection */
		zero_m4(proj);
		proj[3][3] = 1.0f;

		if (texmap->projx != PROJ_N)
			proj[texmap->projx - 1][0] = 1.0f;
		if (texmap->projy != PROJ_N)
			proj[texmap->projy - 1][1] = 1.0f;
		if (texmap->projz != PROJ_N)
			proj[texmap->projz - 1][2] = 1.0f;

		/* scale */
		copy_v3_v3(size, texmap->size);

		if (ELEM(texmap->type, TEXMAP_TYPE_TEXTURE, TEXMAP_TYPE_NORMAL)) {
			/* keep matrix invertible */
			if (fabsf(size[0]) < 1e-5f)
				size[0] = signf(size[0]) * 1e-5f;
			if (fabsf(size[1]) < 1e-5f)
				size[1] = signf(size[1]) * 1e-5f;
			if (fabsf(size[2]) < 1e-5f)
				size[2] = signf(size[2]) * 1e-5f;
		}
		
		size_to_mat4(smat, texmap->size);

		/* rotation */
		eul_to_mat4(rmat, texmap->rot);

		/* translation */
		unit_m4(tmat);
		copy_v3_v3(tmat[3], texmap->loc);

		if (texmap->type == TEXMAP_TYPE_TEXTURE) {
			/* to transform a texture, the inverse transform needs
			 * to be applied to the texture coordinate */
			mul_serie_m4(texmap->mat, tmat, rmat, smat, 0, 0, 0, 0, 0);
			invert_m4(texmap->mat);
		}
		else if (texmap->type == TEXMAP_TYPE_POINT) {
			/* forward transform */
			mul_serie_m4(texmap->mat, tmat, rmat, smat, 0, 0, 0, 0, 0);
		}
		else if (texmap->type == TEXMAP_TYPE_VECTOR) {
			/* no translation for vectors */
			mul_m4_m4m4(texmap->mat, rmat, smat);
		}
		else if (texmap->type == TEXMAP_TYPE_NORMAL) {
			/* no translation for normals, and inverse transpose */
			mul_m4_m4m4(texmap->mat, rmat, smat);
			invert_m4(texmap->mat);
			transpose_m4(texmap->mat);
		}

		/* projection last */
		mul_m4_m4m4(texmap->mat, texmap->mat, proj);

		texmap->flag &= ~TEXMAP_UNIT_MATRIX;
	}
}
コード例 #12
0
ファイル: manipulator.cpp プロジェクト: S-V/Lollipop
void EdGizmo::OnMouseMove( const EdSceneViewport& viewport, const SMouseMoveEvent& args )
{
	AHitProxy* pHitProxy = viewport.objAtCursor;

	const bool bHighlightObjects = true;
	if( bHighlightObjects )
	{
		if( pHitProxy != nil )
		{
			APlaceable* pPlaceable = pHitProxy->IsPlaceable();
			m_hightlighted = pPlaceable;

			HGizmoAxis* pHGizmoAxis = SafeCast<HGizmoAxis>( pHitProxy );
			if( pHGizmoAxis != nil )
			{
				m_highlightedAxes = pHGizmoAxis->axis;
			}
			else
			{
				m_highlightedAxes = EGizmoAxis::GizmoAxis_None;
			}
		}
		else
		{
			m_hightlighted = nil;
		}
	}

	if( viewport.IsDraggingMouse() && m_selected != nil )
	{
		// gizmo pick point, in screen space
		Vec2D	pickPosNDC;
		PointToNDC( viewport, viewport.dragStartPosition.x(), viewport.dragStartPosition.y(), pickPosNDC );
		//DBGOUT("pickPosNDC: %f, %f\n",pickPosNDC.x,pickPosNDC.y);

		Vec2D	currPosNDC;
		PointToNDC( viewport, args.mouseX, args.mouseY, currPosNDC );
		//DBGOUT("currPosNDC: %f, %f\n",currPosNDC.x,currPosNDC.y);

		// we need to convert screen space delta to world space movement
		Vec2D	deltaNDC = currPosNDC - pickPosNDC;
		//dbgout << "delta=" << deltaNDC << dbgout.NewLine();

		switch( m_currentMode )
		{
		case EGizmoMode::Gizmo_Translate :
			if( m_currentAxis == GizmoAxis_None )
			{
				return;
			}
			if( m_currentAxis == GizmoAxis_All )
			{
L_TranslateAll:
				const rxView& eye = viewport.GetView();

				Ray3D	pickRay = GetEyeRay( viewport, currPosNDC );

				FLOAT	prevDist = (m_oldState.translation - eye.origin).LengthSqr();
				if( prevDist < VECTOR_EPSILON )
				{
					return;
				}
				prevDist = mxSqrt(prevDist);


				Vec3D	newEntityPos = eye.origin + pickRay.direction * prevDist;

				m_selected->SetOrigin( newEntityPos );
			}
			else
			{
				Vec3D	gizmoPickPos = F_Get_Translation_Gizmo_Pick_Point_In_World_Space( viewport, pickPosNDC, m_selected, m_currentAxis );
				//Vec3D	centerOfGizmo = m_selected->GetOrigin();
				Vec3D	pointOnGizmo = F_Get_Translation_Gizmo_Pick_Point_In_World_Space( viewport, currPosNDC, m_selected, m_currentAxis );
				Vec3D	translationDelta = pointOnGizmo - gizmoPickPos;

				const FLOAT MAX_TRANSLATION_DIST = 100.0f;
				translationDelta.Clamp(Vec3D(-MAX_TRANSLATION_DIST),Vec3D(MAX_TRANSLATION_DIST));

				Vec3D	newEntityPos = m_oldState.translation + translationDelta;

				m_selected->SetOrigin( newEntityPos );
			}
			break;

		case EGizmoMode::Gizmo_Scale :
			if( m_currentAxis == GizmoAxis_All )
			{
				goto L_TranslateAll;
			}
			else
			{
				//dbgout << "Scaling\n";
				FLOAT mag = deltaNDC.LengthFast();

				FLOAT	newEntityScale = m_oldState.scaleFactor + mag * signf(deltaNDC.x);
				newEntityScale = maxf(newEntityScale,0.01f);

				m_selected->SetScale( newEntityScale );
			}
			break;

		case EGizmoMode::Gizmo_Rotate :
			//if( m_currentAxis == GizmoAxis_None )
			//{
			//	return false;
			//}
			if( m_currentAxis == GizmoAxis_All )
			{
				goto L_TranslateAll;
			}
			else
			{
				//dbgout << "Rotating\n";
				mxUNDONE;
				static FLOAT	ROT_ARC_RADIUS = 1.0f;
				HOT_FLOAT(ROT_ARC_RADIUS);

				// starting point of rotation arc
				Vec3D	vDownPt = ConvertScreenPointToVector(
					viewport,
					viewport.dragStartPosition.x(), viewport.dragStartPosition.y(),
					ROT_ARC_RADIUS
					);

				// current point of rotation arc
				Vec3D	vCurrPt = ConvertScreenPointToVector(
					viewport,
					args.mouseX, args.mouseY,
					ROT_ARC_RADIUS
					);

#if 0
				Quat	qRot = QuatFromBallPoints( vDownPt, vCurrPt );
				qRot.Normalize();
#else
				Vec3D	axis = Cross( vDownPt, vCurrPt );
				axis.Normalize();

				F4		angle = AngleBetween( vDownPt, vCurrPt );
				Quat	qRot( axis, angle );
				qRot.Normalize();
#endif

				Quat	q = qRot * m_oldState.orientation;
				q.Normalize();

				m_selected->SetOrientation(q);
			}
			break;

			mxNO_SWITCH_DEFAULT;
		}
	}
}
コード例 #13
0
ファイル: paint_image_2d.c プロジェクト: sftd/blender
static void paint_2d_lift_soften(ImagePaintState *s, ImBuf *ibuf, ImBuf *ibufb, int *pos, const short is_torus)
{
	bool sharpen = (s->painter->cache.invert ^ ((s->brush->flag & BRUSH_DIR_IN) != 0));
	float threshold = s->brush->sharp_threshold;
	int x, y, xi, yi, xo, yo, xk, yk;
	float count;
	int out_off[2], in_off[2], dim[2];
	int diff_pos[2];
	float outrgb[4];
	float rgba[4];
	BlurKernel *kernel = s->blurkernel;

	dim[0] = ibufb->x;
	dim[1] = ibufb->y;
	in_off[0] = pos[0];
	in_off[1] = pos[1];
	out_off[0] = out_off[1] = 0;

	if (!is_torus) {
		IMB_rectclip(ibuf, ibufb, &in_off[0], &in_off[1], &out_off[0],
		             &out_off[1], &dim[0], &dim[1]);

		if ((dim[0] == 0) || (dim[1] == 0))
			return;
	}

	/* find offset inside mask buffers to sample them */
	sub_v2_v2v2_int(diff_pos, out_off, in_off);

	for (y = 0; y < dim[1]; y++) {
		for (x = 0; x < dim[0]; x++) {
			/* get input pixel */
			xi = in_off[0] + x;
			yi = in_off[1] + y;

			count = 0.0;
			paint_2d_ibuf_rgb_get(ibuf, xi, yi, is_torus, rgba);
			zero_v4(outrgb);

			for (yk = 0; yk < kernel->side; yk++) {
				for (xk = 0; xk < kernel->side; xk++) {
					float x_offs = xk - kernel->pixel_len;
					float y_offs = yk - kernel->pixel_len;
					count += paint_2d_ibuf_add_if(ibuf, xi + signf(x_offs) * fabs(x_offs + 0.51f),
					                               yi + signf(y_offs) * fabs(y_offs + 0.51f), outrgb, is_torus,
					                               kernel->wdata[xk + yk * kernel->side]);
				}
			}

			if (count > 0.0f) {
				mul_v4_fl(outrgb, 1.0f / (float)count);

				if (sharpen) {
					/* subtract blurred image from normal image gives high pass filter */
					sub_v3_v3v3(outrgb, rgba, outrgb);

					/* now rgba_ub contains the edge result, but this should be converted to luminance to avoid
					 * colored speckles appearing in final image, and also to check for threshold */
					outrgb[0] = outrgb[1] = outrgb[2] = rgb_to_grayscale(outrgb);
					if (fabsf(outrgb[0]) > threshold) {
						float mask = BKE_brush_alpha_get(s->scene, s->brush);
						float alpha = rgba[3];
						rgba[3] = outrgb[3] = mask;

						/* add to enhance edges */
						blend_color_add_float(outrgb, rgba, outrgb);
						outrgb[3] = alpha;
					}
					else
						copy_v4_v4(outrgb, rgba);
				}
			}
			else
				copy_v4_v4(outrgb, rgba);
			/* write into brush buffer */
			xo = out_off[0] + x;
			yo = out_off[1] + y;
			paint_2d_ibuf_rgb_set(ibufb, xo, yo, 0, outrgb);
		}
	}
}
コード例 #14
0
static void do_displace(CompBuf *stackbuf, CompBuf *cbuf, CompBuf *vecbuf, float *UNUSED(veccol), CompBuf *xbuf,  CompBuf *ybuf, float *xscale, float *yscale)
{
	ImBuf *ibuf;
	int x, y;
	float p_dx, p_dy;	/* main displacement in pixel space */
	float d_dx, d_dy;
	float dxt, dyt;
	float u, v;
	float xs, ys;
	float vec[3], vecdx[3], vecdy[3];
	float col[3];
	
	ibuf= IMB_allocImBuf(cbuf->x, cbuf->y, 32, 0);
	ibuf->rect_float= cbuf->rect;
	
	for(y=0; y < stackbuf->y; y++) {
		for(x=0; x < stackbuf->x; x++) {
			/* calc pixel coordinates */
			qd_getPixel(vecbuf, x-vecbuf->xof, y-vecbuf->yof, vec);
			
			if (xbuf)
				qd_getPixel(xbuf, x-xbuf->xof, y-xbuf->yof, &xs);
			else
				xs = xscale[0];
			
			if (ybuf)
				qd_getPixel(ybuf, x-ybuf->xof, y-ybuf->yof, &ys);
			else
				ys = yscale[0];

			
			p_dx = vec[0] * xs;
			p_dy = vec[1] * ys;
			
			/* if no displacement, then just copy this pixel */
			if (fabsf(p_dx) < DISPLACE_EPSILON && fabsf(p_dy) < DISPLACE_EPSILON) {
				qd_getPixel(cbuf, x-cbuf->xof, y-cbuf->yof, col);
				qd_setPixel(stackbuf, x, y, col);
				continue;
			}
			
			/* displaced pixel in uv coords, for image sampling */
			u = (x - cbuf->xof - p_dx + 0.5f) / (float)stackbuf->x;
			v = (y - cbuf->yof - p_dy + 0.5f) / (float)stackbuf->y;
			
			
			/* calc derivatives */
			qd_getPixel(vecbuf, x-vecbuf->xof+1, y-vecbuf->yof, vecdx);
			qd_getPixel(vecbuf, x-vecbuf->xof, y-vecbuf->yof+1, vecdy);
			d_dx = vecdx[0] * xs;
			d_dy = vecdy[0] * ys;

			/* clamp derivatives to minimum displacement distance in UV space */
			dxt = p_dx - d_dx;
			dyt = p_dy - d_dy;

			dxt = signf(dxt)*maxf(fabsf(dxt), DISPLACE_EPSILON)/(float)stackbuf->x;
			dyt = signf(dyt)*maxf(fabsf(dyt), DISPLACE_EPSILON)/(float)stackbuf->y;
			
			ibuf_sample(ibuf, u, v, dxt, dyt, col);
			qd_setPixel(stackbuf, x, y, col);
		}
	}
	IMB_freeImBuf(ibuf);
	
	
/* simple method for reference, linear interpolation */
/*	
	int x, y;
	float dx, dy;
	float u, v;
	float vec[3];
	float col[3];
	
	for(y=0; y < stackbuf->y; y++) {
		for(x=0; x < stackbuf->x; x++) {
			qd_getPixel(vecbuf, x, y, vec);
			
			dx = vec[0] * (xscale[0]);
			dy = vec[1] * (yscale[0]);
			
			u = (x - dx + 0.5f) / (float)stackbuf->x;
			v = (y - dy + 0.5f) / (float)stackbuf->y;
			
			qd_getPixelLerp(cbuf, u*cbuf->x - 0.5f, v*cbuf->y - 0.5f, col);
			qd_setPixel(stackbuf, x, y, col);
		}
	}
*/
}