Как насчет добавления кусочка физики в расширенную реальность?
В сегодняшнем сообщении мы заглянем в Silverlight 5 (бета-версия), расширенную реальность и SLARToolkit, благодаря обновлению от Рене Шульте (Rene Schulte).
Когда я читал это сообщение, то вспомнил рекламу Will It Blend, где ведущий бросает в блендер разные вещи и смотрит, сможет ли он с ними справиться… Подобно этому проекту, Рене забрасывает в свой проект SLARToolkit все больше и больше вещей. Сегодня мы посмотрим, как он добавляет в смесь Balder и JigLibX…
Это сообщение содержит новую демонстрацию набора SLARToolkit, использующего трехмерный движок Balder с открытым исходным кодом от моего друга Эйнара Ингебригстена (Einar Ingebrigsten). Эта демонстрация включает также движок физики с открытым исходным кодом JigLibX, которую мой приятель Энди Белью (Andy Beaulieu) перенес на Silverlight. Можно попробовать запустить действующие примеры, если у вас установлена бета-версия Silverlight 5 или же посмотреть видео.
...
Оживление
Чтобы запустить этот пример необходима веб-камера и, по крайней мере, бета-версия среды исполнения Silverlight 5. Она доступна здесь. Кроме того, видео нового примера вставлено в сообщение ниже.
Если вы хотите попробовать запустить пример самостоятельно, то вам необходимо скачать SLAR и L-маркер, напечатать его и держать перед камерой. Маркер(ы) необходимо напечатать не масштабируя их, оригинального размера (80 х 80 мм) и разместить по центру белого квадрата. В качестве альтернативы можно открыть файл маркера на мобильном устройстве и использовать экран устройства как маркер. Также убедитесь, что камера настроена правильно и сцена хорошо освещена и не имеет четких теней. Подробности можно найти в документации по маркерам SLARToolkit.
Как это работает
В этом примере используется поток с видеокамеры, который заполняет прямоугольную форму, также постоянно захватывается видео и скармливает его программе SLARToolkit BitmapMarkerDetector для нахождения маркеров. В результате регистрации определяется матрица преобразования для каждого найденного маркера, которая затем применяется для глобального преобразования кубов и плоскостей.
Я реализовал систему частиц с регулируемым направленным источником, которым можно управлять с помощью разных свойств. Система частиц совершенно общая и может применяться для любых типов частиц (трехмерных объектов). Определение и разрешение столкновений частиц основано на физике твердого тела, и реализовано с помощью библиотеки JigLibX, которую мой приятель Энди Белью, портировал на Silverlight.
Загрузка модели и рендеринг осуществляется с помощью трехмерного механизма Balder. Это совершенно фантастический движок с открытым исходным кодом, созданный Эйнаром Ингебригстеном. Вам надо написать лишь пару строк кода XAML и всё готово. В этом примере используется лишь простая кубическая модель, но в Balder’е есть загрузчики встроенных моделей для загрузки сложных трехмерных моделей и Эйнар предоставляет большую библиотеку примеров. Он также предоставил движок для нескольких других платформ, включая Windows Phone 7, OpenGL и даже имеет четкий план нейтрализации программных ошибок рендеринга. Прочтите это блог здесь.
Как часть этого примера мне понадобились некоторые векторные и кватернионные методы, отсутствующие в Balder’е. Я предоставляю их и общую систему частиц для проекта Balder. Вы можете свободно использовать систему частиц и другие методы в своих проектах Balder.
Давайте взглянем на проект...
private void DetectMarkers(WriteableBitmap bmp)
{
// Init. here because the captureSource.VideoCaptureDevice.DesiredFormat getter is not reliable and throws an Exception
if (!isInit)
{
// Init AR
arDetector.Initialize(bmp.PixelWidth, bmp.PixelHeight, Game.Camera.Near, Game.Camera.Far, slarMarker);
isInit = true;
}
// Detect
var dr = arDetector.DetectAllMarkers(bmp);
// Reused for marker highlighting
bmp.Clear();
ViewportOverlay.Source = bmp;
if (dr.HasResults)
{
var transformation = Balder.Math.Matrix.CreateTranslation(0, -5, 0) * Balder.Math.Matrix.CreateRotationX(90) * dr[0].Transformation.ToBalder();
Game.SetWorldMatrix(transformation);
// Highlight detected markers
var txt = String.Empty;
foreach (var r in dr)
{
bmp.DrawQuad((int)r.Square.P1.X, (int)r.Square.P1.Y, (int)r.Square.P2.X, (int)r.Square.P2.Y, (int)r.Square.P3.X, (int)r.Square.P3.Y, (int)r.Square.P4.X, (int)r.Square.P4.Y, Colors.Red);
txt += String.Format("{0}.Confidence = {1:0.00} ", r.Marker.Name, r.Confidence);
}
}
}
using Balder;
using Balder.Execution;
using Balder.Materials;
using Balder.Math;
using JigLibX.Collision;
using JigLibX.Physics;
namespace SLARToolKitBalderSampleSL5
{
public class SlarGame : Game
{
const float UpdateStep = 0.04f;
readonly PhysicsSystem world;
readonly Cuboid ground;
public SlarParticleSystem ParticleSystem { get; private set; }
public SlarGame()
{
ParticleSystem = new SlarParticleSystem();
world = new PhysicsSystem
{
CollisionSystem = new CollisionSystemSAP { UseSweepTests = true },
EnableFreezing = true,
SolverType = PhysicsSystem.Solver.Normal,
NumCollisionIterations = 8,
NumContactIterations = 8,
NumPenetrationRelaxtionTimesteps = 15
};
ground = new Cuboid(new Vector(300, 1, 300))
{
Material = new Material {Diffuse = new Color(50, 50, 50, 100), DoubleSided = true},
IsFixed = true,
};
}
Вот несколько ссылок, которые могут оказаться интересными: