void CWeaponProjectile::DrawUnitPart()
{
	float3 interPos=pos+speed*gu->timeOffset;
	float3 dir(speed);
	dir.Normalize();
	glPushMatrix();
	float3 rightdir;
	if(dir.y!=1)
		rightdir=dir.cross(UpVector);
	else
		rightdir=float3(1,0,0);
	rightdir.Normalize();
	float3 updir(rightdir.cross(dir));

	CMatrix44f transMatrix;
	transMatrix[0]=-rightdir.x;
	transMatrix[1]=-rightdir.y;
	transMatrix[2]=-rightdir.z;
	transMatrix[4]=updir.x;
	transMatrix[5]=updir.y;
	transMatrix[6]=updir.z;
	transMatrix[8]=dir.x;
	transMatrix[9]=dir.y;
	transMatrix[10]=dir.z;
	transMatrix[12]=interPos.x;
	transMatrix[13]=interPos.y;
	transMatrix[14]=interPos.z;
	glMultMatrixf(&transMatrix[0]);

	glCallList(modelDispList);
	glPopMatrix();
}
dVector CustomPlayerController::CalculateDesiredVelocity (dFloat forwardSpeed, dFloat lateralSpeed, dFloat verticalSpeed, const dVector& gravity, dFloat timestep) const
{
	dMatrix matrix;
	NewtonBodyGetMatrix(m_body, &matrix[0][0]);
	dVector updir (matrix.RotateVector(m_upVector));
	dVector frontDir (matrix.RotateVector(m_frontVector));
	dVector rightDir (frontDir * updir);

	dVector veloc (0.0f, 0.0f, 0.0f, 0.0f);
	if ((verticalSpeed <= 0.0f) && (m_groundPlane % m_groundPlane) > 0.0f) {
		// plane is supported by a ground plane, apply the player input velocity
		if ((m_groundPlane % updir) >= m_maxSlope) {
			// player is in a legal slope, he is in full control of his movement
			dVector bodyVeloc;
			NewtonBodyGetVelocity(m_body, &bodyVeloc[0]);
			veloc = updir.Scale(bodyVeloc % updir) + gravity.Scale (timestep) + frontDir.Scale (forwardSpeed) + rightDir.Scale (lateralSpeed) + updir.Scale(verticalSpeed);
			veloc += (m_groundVelocity - updir.Scale (updir % m_groundVelocity));

			dFloat speedLimitMag2 = forwardSpeed * forwardSpeed + lateralSpeed * lateralSpeed + verticalSpeed * verticalSpeed + m_groundVelocity % m_groundVelocity + 0.1f;
			dFloat speedMag2 = veloc % veloc;
			if (speedMag2 > speedLimitMag2) {
				veloc = veloc.Scale (dSqrt (speedLimitMag2 / speedMag2));
			}

			dFloat normalVeloc = m_groundPlane % (veloc - m_groundVelocity);
			if (normalVeloc < 0.0f) {
				veloc -= m_groundPlane.Scale (normalVeloc);
			}
		} else {
			// player is in an illegal ramp, he slides down hill an loses control of his movement 
			NewtonBodyGetVelocity(m_body, &veloc[0]);
			veloc += updir.Scale(verticalSpeed);
			veloc += gravity.Scale (timestep);
			dFloat normalVeloc = m_groundPlane % (veloc - m_groundVelocity);
			if (normalVeloc < 0.0f) {
				veloc -= m_groundPlane.Scale (normalVeloc);
			}
		}
	} else {
		// player is on free fall, only apply the gravity
		NewtonBodyGetVelocity(m_body, &veloc[0]);
		veloc += updir.Scale(verticalSpeed);
		veloc += gravity.Scale (timestep);
	}
	return veloc;
}
Exemple #3
0
void CWeaponProjectile::DrawUnitPart()
{
	float3 dir(speed);
	dir.Normalize();
	glPushMatrix();
	float3 rightdir;

	if (dir.y != 1)
		rightdir = dir.cross(UpVector);
	else
		rightdir = float3(1, 0, 0);

	rightdir.Normalize();
	float3 updir(rightdir.cross(dir));

	CMatrix44f transMatrix(drawPos,-rightdir,updir,dir);

	glMultMatrixf(&transMatrix[0]);
	glCallList(s3domodel->rootobject->displist); // dont cache displists because of delayed loading
	glPopMatrix();
}
void CWeaponProjectile::DrawUnitPart()
{
	float3 interPos = pos + speed * gu->timeOffset;
	float3 dir(speed);
	dir.Normalize();
	glPushMatrix();
	float3 rightdir;

	if (dir.y != 1)
		rightdir = dir.cross(UpVector);
	else
		rightdir = float3(1, 0, 0);

	rightdir.Normalize();
	float3 updir(rightdir.cross(dir));

	CMatrix44f transMatrix(interPos,-rightdir,updir,dir);

	glMultMatrixf(&transMatrix[0]);
	glCallList(modelDispList);
	glPopMatrix();
}
Exemple #5
0
void TransCoder::pipeRun(int ind)
{
    GstElement *source, *dec, *conv, *encoder, *muxer, *fileout, *tagger, *volume;
    GstBus *bus;
    GstState state;
    GstPad *audiopad;//, *encoderpad;

    numTrack = ind;
    bool preenc;
    int vbr = 0;

    loop = g_main_loop_new (NULL, FALSE);

    pipeline = gst_pipeline_new ("audio-transcoder");

    // Входной файл
    source   = gst_element_factory_make ("filesrc", "file-source");
    g_object_set (source, "location", localFileNamesEncoder->fromUnicode(refparser->getSoundFile()).data(), NULL);

    dec = gst_element_factory_make ("decodebin", "decoder");
    g_signal_connect (dec, "new-decoded-pad", G_CALLBACK (cb_newpad), NULL);
    gst_bin_add_many (GST_BIN (pipeline), source, dec, NULL);
    gst_element_link (source, dec);

    audio = gst_bin_new ("audiobin");
    conv = gst_element_factory_make ("audioconvert", "aconv");
    volume = gst_element_factory_make ("volume", "vol");
    audiopad = gst_element_get_static_pad (conv, "sink");
    fileout = gst_element_factory_make ("filesink", "file-out");

    // Выходной файл
    QRegExp rxFileSlash("/");
    QRegExp rxTilda("^~(.*)");
    QString filename;
    QTextStream out(stdout);
    QString comment = trUtf8("CuePlayer ") + qApp->applicationVersion();
    QString trackName = refparser->getTrackTitle(ind);
    QString title = refparser->getTitle();
    trackName.replace(rxFileSlash, trUtf8("⁄"));
    title.replace(rxFileSlash, trUtf8("⁄"));
    if (rxTilda.indexIn(lineEdit->text()) != -1)
        lineEdit->setText(QDir::homePath() + rxTilda.cap(1));
    QDir updir(lineEdit->text());
    if (!updir.exists())
        updir.mkdir(lineEdit->text());
    QString dirname = lineEdit->text() + "/" + title;
    QDir dir(dirname);
    if (!dir.exists())
        dir.mkdir(dirname);
    if (ind < 10)
        filename = dirname + "/" + "0" + QString::number(ind,10) + " - " + trackName + "." + containerBox->currentText();
    else
        filename = dirname + "/" + QString::number(ind,10) + " - " + trackName + "." + containerBox->currentText();
    g_object_set (fileout, "location", localFileNamesEncoder->fromUnicode(filename).data(), NULL);

    tmpfile.setFileName(dirname + "/" + QString::number(ind,10) + " - " + trackName + ".tmp");

    switch (codecBox->currentIndex())
    {
    case CODEC_VORBIS:
        if (tmpfile.exists())
        {
            g_object_set (source, "location", localFileNamesEncoder->fromUnicode(tmpfile.fileName()).data(), NULL);
            encoder = gst_element_factory_make ("vorbisenc", "audio-encoder");
            tagger = gst_element_factory_make ("vorbistag", "tagger");
            muxer = gst_element_factory_make ("oggmux", "audio-muxer");
            gst_bin_add_many (GST_BIN (audio), conv, encoder, tagger, muxer, fileout, NULL);
            gst_element_link_many (conv, encoder, tagger, muxer, fileout, NULL);
            if (!settings.value("preferences/vorbisquality").isNull())
            {
                g_object_set (encoder,
                              "max-bitrate", settings.value("preferences/vorbismaxbitrate").toInt(),
                              "bitrate", settings.value("preferences/vorbisbitrate").toInt(),
                              "min-bitrate", settings.value("preferences/vorbisminbitrate").toInt(),
                              "quality", settings.value("preferences/vorbisquality").toDouble()/10,
                              "managed", settings.value("preferences/vorbismanaged").toBool(),
                              NULL);
            }
            gst_tag_setter_add_tags (GST_TAG_SETTER (tagger),
                                     GST_TAG_MERGE_REPLACE_ALL,
                                     GST_TAG_TITLE, refparser->getTrackTitle(ind).toUtf8().data(),
                                     GST_TAG_ARTIST, refparser->getPerformer().toUtf8().data(),
                                     GST_TAG_TRACK_NUMBER, ind,
                                     GST_TAG_TRACK_COUNT, refparser->getTrackNumber(),
                                     GST_TAG_ALBUM, refparser->getAlbum().toUtf8().data(),
                                     GST_TAG_ENCODER, APPNAME,
                                     GST_TAG_ENCODER_VERSION, qApp->applicationVersion().toUtf8().data(),
                                     GST_TAG_COMMENT, comment.toUtf8().data(),
                                     GST_TAG_CODEC, "vorbis",
                                     NULL);
            containerBox->setCurrentIndex(CODEC_VORBIS);
        }
        else
        {
            preenc = true;
            encoder = gst_element_factory_make ("flacenc", "audio-encoder");
            g_object_set(encoder, "quality", 0, NULL);
            gst_bin_add_many (GST_BIN (audio), conv, volume, encoder, fileout, NULL);
            gst_element_link_many (conv, volume, encoder, fileout, NULL);
            g_object_set (volume, "mute", true, NULL);
            g_object_set (fileout, "location", localFileNamesEncoder->fromUnicode(tmpfile.fileName()).data(), NULL);
        }
        break;
    case CODEC_LAME:
        encoder = gst_element_factory_make ("lame", "audio-encoder");
        muxer = gst_element_factory_make ("id3v2mux", "audio-muxer");
        gst_bin_add_many (GST_BIN (audio), conv, encoder, muxer, fileout, NULL);
        gst_element_link_many (conv, encoder, muxer, fileout, NULL);

        if (settings.value("preferences/lamevbr").toInt())
            vbr = settings.value("preferences/lamevbr").toInt() + 1;

        if (!settings.value("preferences/lamequality").isNull())
        {
            g_object_set (encoder,
                          "bitrate", bitrateList.at(settings.value("preferences/lamebitrate").toInt()),
                          //"compression-ratio", settings.value("preferences/lamecompressionratio").toInt(), // Баг. Перекрывает VBR
                          "quality", settings.value("preferences/lamequality").toInt(),
                          "mode", settings.value("preferences/lamemode").toInt(),
                          "force-ms", settings.value("preferences/lameforcems").toBool(),
                          "free-format", settings.value("preferences/lamefreeformat").toBool(),
                          "copyright", settings.value("preferences/lamecopyright").toBool(),
                          "original", settings.value("preferences/lameoriginal").toBool(),
                          "error-protection", settings.value("preferences/lameerrprot").toBool(),
                          "padding-type", settings.value("preferences/lamepaddingtype").toInt(),
                          "extension", settings.value("preferences/lameextension").toBool(),
                          "strict-iso", settings.value("preferences/lamestrictiso").toBool(),
                          "vbr", vbr,
                          "disable-reservoir", settings.value("preferences/lamedisrese").toBool(),
                          NULL);
        }
        gst_tag_setter_add_tags (GST_TAG_SETTER (muxer),
                                 GST_TAG_MERGE_REPLACE_ALL,
                                 GST_TAG_TITLE, refparser->getTrackTitle(ind).toUtf8().data(),
                                 GST_TAG_ARTIST, refparser->getPerformer().toUtf8().data(),
                                 GST_TAG_TRACK_NUMBER, ind,
                                 GST_TAG_TRACK_COUNT, refparser->getTrackNumber(),
                                 GST_TAG_ALBUM, refparser->getAlbum().toUtf8().data(),
                                 GST_TAG_ENCODER, APPNAME,
                                 GST_TAG_ENCODER_VERSION, qApp->applicationVersion().toUtf8().data(),
                                 GST_TAG_COMMENT, comment.toUtf8().data(),
                                 GST_TAG_CODEC, "lame",
                                 NULL);
        containerBox->setCurrentIndex(CODEC_LAME);
        break;
    case CODEC_FLAC:
        encoder = gst_element_factory_make ("flacenc", "audio-encoder");
        tagger = gst_element_factory_make ("flactag", "tagger");
        if (!settings.value("preferences/flacquality").isNull())
        {
            g_object_set (encoder,
                          "quality", settings.value("preferences/flacquality").toInt(),
                          "streamable-subset", settings.value("preferences/flacstreamablesubset").toBool(),
                          "mid-side-stereo", settings.value("preferences/flacmidsidestereo").toBool(),
                          "loose-mid-side-stereo", settings.value("preferences/flacloosemidsidestereo").toBool(),
                          "blocksize", settings.value("preferences/flacblocksize").toInt(),
                          "max-lpc-order", settings.value("preferences/flacmaxlpcorder").toInt(),
                          "qlp-coeff-precision", settings.value("preferences/flacqlpcoeffprecision").toInt(),
                          "qlp-coeff-prec-search", settings.value("preferences/flacqlpcoeffprecsearch").toBool(),
                          "escape-coding", settings.value("preferences/flacescapecoding").toBool(),
                          "exhaustive-model-search", settings.value("preferences/flacexhaustivemodelsearch").toBool(),
                          "min-residual-partition-order", settings.value("preferences/flacminresidualpartitionorder").toInt(),
                          "max-residual-partition-order", settings.value("preferences/flacmaxresidualpartitionorder").toInt(),
                          "rice-parameter-search-dist", settings.value("preferences/flacriceparametersearchdist").toInt(),
                          NULL);
        }
        gst_bin_add_many (GST_BIN (audio), conv, encoder, tagger, fileout, NULL);
        gst_element_link_many (conv, encoder, tagger, fileout, NULL);
        gst_tag_setter_add_tags (GST_TAG_SETTER (tagger),
                                 GST_TAG_MERGE_REPLACE_ALL,
                                 GST_TAG_TITLE, refparser->getTrackTitle(ind).toUtf8().data(),
                                 GST_TAG_ARTIST, refparser->getPerformer().toUtf8().data(),
                                 GST_TAG_TRACK_NUMBER, ind,
                                 GST_TAG_TRACK_COUNT, refparser->getTrackNumber(),
                                 GST_TAG_ALBUM, refparser->getAlbum().toUtf8().data(),
                                 GST_TAG_ENCODER, APPNAME,
                                 GST_TAG_ENCODER_VERSION, qApp->applicationVersion().toUtf8().data(),
                                 GST_TAG_COMMENT, comment.toUtf8().data(),
                                 GST_TAG_CODEC, "flac",
                                 NULL);
        containerBox->setCurrentIndex(CODEC_FLAC);
        break;
    case CODEC_FAAC:
        encoder = gst_element_factory_make ("faac", "audio-encoder");
        gst_bin_add_many (GST_BIN (audio), conv, encoder, fileout, NULL);
        gst_element_link_many (conv, encoder, fileout, NULL);
        if (!settings.value("preferences/faacprofile").isNull())
        {
            g_object_set(encoder,
                         "outputformat", settings.value("preferences/faacoutputformat").toInt(),
                         "bitrate", settings.value("preferences/faacbitrate").toInt(),
                         "profile", settings.value("preferences/faacprofile").toInt()+1,
                         "tns", settings.value("preferences/faactns").toBool(),
                         "midside", settings.value("preferences/faacmidside").toBool(),
                         "shortctl", settings.value("preferences/faacshortctl").toInt(),
                         NULL);
        }
        containerBox->setCurrentIndex(CODEC_FAAC);
        break;
    case CODEC_NO:
    default:
        break;
    }

    gst_element_add_pad (audio, gst_ghost_pad_new ("sink", audiopad));
    gst_object_unref (audiopad);
    gst_bin_add (GST_BIN (pipeline), audio);

    bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
    gst_bus_add_watch (bus, bus_call, loop);
    gst_object_unref (bus);

    //g_signal_connect (pipeline, "deep-notify", G_CALLBACK (gst_object_default_deep_notify), NULL); // Дебаг!
    out << trUtf8("Кодируется: ") << refparser->getSoundFile() << endl;

    gst_element_set_state (pipeline, GST_STATE_PLAYING);

    gst_element_get_state( GST_ELEMENT(pipeline), &state, NULL, GST_MSECOND * 300);
    if (state == GST_STATE_PLAYING)
    {
        timer->start(TIME);
        if (ind == refparser->getTrackNumber())
            setTrackTime(refparser->getTrackIndex(ind),saveTotalTime);
        else
            setTrackTime(refparser->getTrackIndex(ind),refparser->getTrackIndex(ind+1));
        if (preenc)
            g_object_set (volume, "mute", false, NULL);
        g_print ("Запущено...\n");
        g_main_loop_run (loop);
    }
    else
    {
        out << trUtf8("Ошибка перехода в PLAYING\n");
        transcode = false;
        stopAll();
    }
}
void CustomPlayerController::PostUpdate(dFloat timestep, int threadIndex)
{
	dMatrix matrix; 
	dQuaternion bodyRotation;
	dVector veloc(0.0f, 0.0f, 0.0f, 0.0f); 
	dVector omega(0.0f, 0.0f, 0.0f, 0.0f);  

	CustomPlayerControllerManager* const manager = (CustomPlayerControllerManager*) GetManager();
	NewtonWorld* const world = manager->GetWorld();

	// apply the player motion, by calculation the desired plane linear and angular velocity
	manager->ApplyPlayerMove (this, timestep);

	// get the body motion state 
	NewtonBodyGetMatrix(m_body, &matrix[0][0]);
	NewtonBodyGetVelocity(m_body, &veloc[0]);
	NewtonBodyGetOmega(m_body, &omega[0]);

	// integrate body angular velocity
	NewtonBodyGetRotation (m_body, &bodyRotation.m_q0); 
	bodyRotation = bodyRotation.IntegrateOmega(omega, timestep);
	matrix = dMatrix (bodyRotation, matrix.m_posit);

	// integrate linear velocity
	dFloat normalizedTimeLeft = 1.0f; 
	dFloat step = timestep * dSqrt (veloc % veloc) ;
	dFloat descreteTimeStep = timestep * (1.0f / D_DESCRETE_MOTION_STEPS);
	int prevContactCount = 0;
	CustomControllerConvexCastPreFilter castFilterData (m_body);
	NewtonWorldConvexCastReturnInfo prevInfo[PLAYER_CONTROLLER_MAX_CONTACTS];

	dVector updir (matrix.RotateVector(m_upVector));

	dVector scale;
	NewtonCollisionGetScale (m_upperBodyShape, &scale.m_x, &scale.m_y, &scale.m_z);
	//const dFloat radio = m_outerRadio * 4.0f;
	const dFloat radio = (m_outerRadio + m_restrainingDistance) * 4.0f;
	NewtonCollisionSetScale (m_upperBodyShape, m_height - m_stairStep, radio, radio);


	NewtonWorldConvexCastReturnInfo upConstratint;
	memset (&upConstratint, 0, sizeof (upConstratint));
	upConstratint.m_normal[0] = m_upVector.m_x;
	upConstratint.m_normal[1] = m_upVector.m_y;
	upConstratint.m_normal[2] = m_upVector.m_z;
	upConstratint.m_normal[3] = m_upVector.m_w;

	for (int j = 0; (j < D_PLAYER_MAX_INTERGRATION_STEPS) && (normalizedTimeLeft > 1.0e-5f); j ++ ) {
		if ((veloc % veloc) < 1.0e-6f) {
			break;
		}

		dFloat timetoImpact;
		NewtonWorldConvexCastReturnInfo info[PLAYER_CONTROLLER_MAX_CONTACTS];
		dVector destPosit (matrix.m_posit + veloc.Scale (timestep));
		int contactCount = NewtonWorldConvexCast (world, &matrix[0][0], &destPosit[0], m_upperBodyShape, &timetoImpact, &castFilterData, CustomControllerConvexCastPreFilter::Prefilter, info, sizeof (info) / sizeof (info[0]), threadIndex);
		if (contactCount) {
			contactCount = manager->ProcessContacts (this, info, contactCount);
		}

		if (contactCount) {
			matrix.m_posit += veloc.Scale (timetoImpact * timestep);
			if (timetoImpact > 0.0f) {
				matrix.m_posit -= veloc.Scale (D_PLAYER_CONTACT_SKIN_THICKNESS / dSqrt (veloc % veloc)) ; 
			}

			normalizedTimeLeft -= timetoImpact;

			dFloat speed[PLAYER_CONTROLLER_MAX_CONTACTS * 2];
			dFloat bounceSpeed[PLAYER_CONTROLLER_MAX_CONTACTS * 2];
			dVector bounceNormal[PLAYER_CONTROLLER_MAX_CONTACTS * 2];

			for (int i = 1; i < contactCount; i ++) {
				dVector n0 (info[i-1].m_normal);
				for (int j = 0; j < i; j ++) {
					dVector n1 (info[j].m_normal);
					if ((n0 % n1) > 0.9999f) {
						info[i] = info[contactCount - 1];
						i --;
						contactCount --;
						break;
					}
				}
			}

			int count = 0;
			if (!m_isJumping) {
				upConstratint.m_point[0] = matrix.m_posit.m_x;
				upConstratint.m_point[1] = matrix.m_posit.m_y;
				upConstratint.m_point[2] = matrix.m_posit.m_z;
				upConstratint.m_point[3] = matrix.m_posit.m_w;

				speed[count] = 0.0f;
				bounceNormal[count] = dVector (upConstratint.m_normal);
				bounceSpeed[count] = CalculateContactKinematics(veloc, &upConstratint);
				count ++;
			}

			for (int i = 0; i < contactCount; i ++) {
				speed[count] = 0.0f;
				bounceNormal[count] = dVector (info[i].m_normal);
				bounceSpeed[count] = CalculateContactKinematics(veloc, &info[i]);
				count ++;
			}

			for (int i = 0; i < prevContactCount; i ++) {
				speed[count] = 0.0f;
				bounceNormal[count] = dVector (prevInfo[i].m_normal);
				bounceSpeed[count] = CalculateContactKinematics(veloc, &prevInfo[i]);
				count ++;
			}

			dFloat residual = 10.0f;
			dVector auxBounceVeloc (0.0f, 0.0f, 0.0f, 0.0f);
			for (int i = 0; (i < D_PLAYER_MAX_SOLVER_ITERATIONS) && (residual > 1.0e-3f); i ++) {
				residual = 0.0f;
				for (int k = 0; k < count; k ++) {
					dVector normal (bounceNormal[k]);
					dFloat v = bounceSpeed[k] - normal % auxBounceVeloc;
					dFloat x = speed[k] + v;
					if (x < 0.0f) {
						v = 0.0f;
						x = 0.0f;
					}

					if (dAbs (v) > residual) {
						residual = dAbs (v);
					}

					auxBounceVeloc += normal.Scale (x - speed[k]);
					speed[k] = x;
				}
			}

			dVector velocStep (0.0f, 0.0f, 0.0f, 0.0f);
			for (int i = 0; i < count; i ++) {
				dVector normal (bounceNormal[i]);
				velocStep += normal.Scale (speed[i]);
			}
			veloc += velocStep;

			dFloat velocMag2 = velocStep % velocStep;
			if (velocMag2 < 1.0e-6f) {
				dFloat advanceTime = dMin (descreteTimeStep, normalizedTimeLeft * timestep);
				matrix.m_posit += veloc.Scale (advanceTime);
				normalizedTimeLeft -= advanceTime / timestep;
			}

			prevContactCount = contactCount;
			memcpy (prevInfo, info, prevContactCount * sizeof (NewtonWorldConvexCastReturnInfo));

		} else {
			matrix.m_posit = destPosit;
			matrix.m_posit.m_w = 1.0f;
			break;
		}
	}
	NewtonCollisionSetScale (m_upperBodyShape, scale.m_x, scale.m_y, scale.m_z);

	// determine if player is standing on some plane
	dMatrix supportMatrix (matrix);
	supportMatrix.m_posit += updir.Scale (m_sphereCastOrigin);
	if (m_isJumping) {
		dVector dst (matrix.m_posit);
		UpdateGroundPlane (matrix, supportMatrix, dst, threadIndex);
	} else {
		step = dAbs (updir % veloc.Scale (timestep));
		dFloat castDist = ((m_groundPlane % m_groundPlane) > 0.0f) ? m_stairStep : step;
		dVector dst (matrix.m_posit - updir.Scale (castDist * 2.0f));
		UpdateGroundPlane (matrix, supportMatrix, dst, threadIndex);
	}

	// set player velocity, position and orientation
	NewtonBodySetVelocity(m_body, &veloc[0]);
	NewtonBodySetMatrix (m_body, &matrix[0][0]);
}