|
@@ -1,5 +1,5 @@
|
|
|
//
|
|
//
|
|
|
-// Copyright (c) 2008-2015 the Urho3D project.
|
|
|
|
|
|
|
+// Copyright (c) 2008-2016 the Urho3D project.
|
|
|
//
|
|
//
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
// of this software and associated documentation files (the "Software"), to deal
|
|
@@ -25,12 +25,11 @@
|
|
|
#include "../Core/Context.h"
|
|
#include "../Core/Context.h"
|
|
|
#include "../Core/Profiler.h"
|
|
#include "../Core/Profiler.h"
|
|
|
#include "../Graphics/Batch.h"
|
|
#include "../Graphics/Batch.h"
|
|
|
-#include "../Atomic3D/BillboardSet.h"
|
|
|
|
|
|
|
+#include "../Graphics/BillboardSet.h"
|
|
|
#include "../Graphics/Camera.h"
|
|
#include "../Graphics/Camera.h"
|
|
|
#include "../Graphics/Geometry.h"
|
|
#include "../Graphics/Geometry.h"
|
|
|
#include "../Graphics/Graphics.h"
|
|
#include "../Graphics/Graphics.h"
|
|
|
#include "../Graphics/IndexBuffer.h"
|
|
#include "../Graphics/IndexBuffer.h"
|
|
|
-#include "../Graphics/Material.h"
|
|
|
|
|
#include "../Graphics/OctreeQuery.h"
|
|
#include "../Graphics/OctreeQuery.h"
|
|
|
#include "../Graphics/VertexBuffer.h"
|
|
#include "../Graphics/VertexBuffer.h"
|
|
|
#include "../IO/MemoryBuffer.h"
|
|
#include "../IO/MemoryBuffer.h"
|
|
@@ -39,7 +38,7 @@
|
|
|
|
|
|
|
|
#include "../DebugNew.h"
|
|
#include "../DebugNew.h"
|
|
|
|
|
|
|
|
-namespace Atomic
|
|
|
|
|
|
|
+namespace Urho3D
|
|
|
{
|
|
{
|
|
|
|
|
|
|
|
extern const char* GEOMETRY_CATEGORY;
|
|
extern const char* GEOMETRY_CATEGORY;
|
|
@@ -53,22 +52,13 @@ const char* faceCameraModeNames[] =
|
|
|
"Rotate Y",
|
|
"Rotate Y",
|
|
|
"LookAt XYZ",
|
|
"LookAt XYZ",
|
|
|
"LookAt Y",
|
|
"LookAt Y",
|
|
|
|
|
+ "Direction",
|
|
|
0
|
|
0
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
inline bool CompareBillboards(Billboard* lhs, Billboard* rhs)
|
|
inline bool CompareBillboards(Billboard* lhs, Billboard* rhs)
|
|
|
{
|
|
{
|
|
|
- return lhs->GetSortDistance() > rhs->GetSortDistance();
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-Billboard::Billboard()
|
|
|
|
|
-{
|
|
|
|
|
-
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-Billboard::~Billboard()
|
|
|
|
|
-{
|
|
|
|
|
-
|
|
|
|
|
|
|
+ return lhs->sortDistance_ > rhs->sortDistance_;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
BillboardSet::BillboardSet(Context* context) :
|
|
BillboardSet::BillboardSet(Context* context) :
|
|
@@ -78,6 +68,7 @@ BillboardSet::BillboardSet(Context* context) :
|
|
|
relative_(true),
|
|
relative_(true),
|
|
|
scaled_(true),
|
|
scaled_(true),
|
|
|
sorted_(false),
|
|
sorted_(false),
|
|
|
|
|
+ fixedScreenSize_(false),
|
|
|
faceCameraMode_(FC_ROTATE_XYZ),
|
|
faceCameraMode_(FC_ROTATE_XYZ),
|
|
|
geometry_(new Geometry(context)),
|
|
geometry_(new Geometry(context)),
|
|
|
vertexBuffer_(new VertexBuffer(context_)),
|
|
vertexBuffer_(new VertexBuffer(context_)),
|
|
@@ -85,11 +76,13 @@ BillboardSet::BillboardSet(Context* context) :
|
|
|
bufferSizeDirty_(true),
|
|
bufferSizeDirty_(true),
|
|
|
bufferDirty_(true),
|
|
bufferDirty_(true),
|
|
|
forceUpdate_(false),
|
|
forceUpdate_(false),
|
|
|
|
|
+ geometryTypeUpdate_(false),
|
|
|
sortThisFrame_(false),
|
|
sortThisFrame_(false),
|
|
|
|
|
+ hasOrthoCamera_(false),
|
|
|
sortFrameNumber_(0),
|
|
sortFrameNumber_(0),
|
|
|
previousOffset_(Vector3::ZERO)
|
|
previousOffset_(Vector3::ZERO)
|
|
|
{
|
|
{
|
|
|
- geometry_->SetVertexBuffer(0, vertexBuffer_, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1 | MASK_TEXCOORD2);
|
|
|
|
|
|
|
+ geometry_->SetVertexBuffer(0, vertexBuffer_);
|
|
|
geometry_->SetIndexBuffer(indexBuffer_);
|
|
geometry_->SetIndexBuffer(indexBuffer_);
|
|
|
|
|
|
|
|
batches_.Resize(1);
|
|
batches_.Resize(1);
|
|
@@ -106,22 +99,23 @@ void BillboardSet::RegisterObject(Context* context)
|
|
|
{
|
|
{
|
|
|
context->RegisterFactory<BillboardSet>(GEOMETRY_CATEGORY);
|
|
context->RegisterFactory<BillboardSet>(GEOMETRY_CATEGORY);
|
|
|
|
|
|
|
|
- ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
|
|
|
|
|
- MIXED_ACCESSOR_ATTRIBUTE("Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()),
|
|
|
|
|
|
|
+ URHO3D_ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
|
|
|
|
|
+ URHO3D_MIXED_ACCESSOR_ATTRIBUTE("Material", GetMaterialAttr, SetMaterialAttr, ResourceRef, ResourceRef(Material::GetTypeStatic()),
|
|
|
AM_DEFAULT);
|
|
AM_DEFAULT);
|
|
|
- ACCESSOR_ATTRIBUTE("Relative Position", IsRelative, SetRelative, bool, true, AM_DEFAULT);
|
|
|
|
|
- ACCESSOR_ATTRIBUTE("Relative Scale", IsScaled, SetScaled, bool, true, AM_DEFAULT);
|
|
|
|
|
- ACCESSOR_ATTRIBUTE("Sort By Distance", IsSorted, SetSorted, bool, false, AM_DEFAULT);
|
|
|
|
|
- ACCESSOR_ATTRIBUTE("Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
|
|
|
|
|
- ATTRIBUTE("Cast Shadows", bool, castShadows_, false, AM_DEFAULT);
|
|
|
|
|
- ENUM_ATTRIBUTE("Face Camera Mode", faceCameraMode_, faceCameraModeNames, FC_ROTATE_XYZ, AM_DEFAULT);
|
|
|
|
|
- ACCESSOR_ATTRIBUTE("Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
|
|
|
|
|
- ACCESSOR_ATTRIBUTE("Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
|
|
|
|
|
- ACCESSOR_ATTRIBUTE("Animation LOD Bias", GetAnimationLodBias, SetAnimationLodBias, float, 1.0f, AM_DEFAULT);
|
|
|
|
|
- COPY_BASE_ATTRIBUTES(Drawable);
|
|
|
|
|
- MIXED_ACCESSOR_ATTRIBUTE("Billboards", GetBillboardsAttr, SetBillboardsAttr, VariantVector, Variant::emptyVariantVector,
|
|
|
|
|
|
|
+ URHO3D_ACCESSOR_ATTRIBUTE("Relative Position", IsRelative, SetRelative, bool, true, AM_DEFAULT);
|
|
|
|
|
+ URHO3D_ACCESSOR_ATTRIBUTE("Relative Scale", IsScaled, SetScaled, bool, true, AM_DEFAULT);
|
|
|
|
|
+ URHO3D_ACCESSOR_ATTRIBUTE("Sort By Distance", IsSorted, SetSorted, bool, false, AM_DEFAULT);
|
|
|
|
|
+ URHO3D_ACCESSOR_ATTRIBUTE("Fixed Screen Size", IsFixedScreenSize, SetFixedScreenSize, bool, false, AM_DEFAULT);
|
|
|
|
|
+ URHO3D_ACCESSOR_ATTRIBUTE("Can Be Occluded", IsOccludee, SetOccludee, bool, true, AM_DEFAULT);
|
|
|
|
|
+ URHO3D_ATTRIBUTE("Cast Shadows", bool, castShadows_, false, AM_DEFAULT);
|
|
|
|
|
+ URHO3D_ENUM_ACCESSOR_ATTRIBUTE("Face Camera Mode", GetFaceCameraMode, SetFaceCameraMode, FaceCameraMode, faceCameraModeNames, FC_ROTATE_XYZ, AM_DEFAULT);
|
|
|
|
|
+ URHO3D_ACCESSOR_ATTRIBUTE("Draw Distance", GetDrawDistance, SetDrawDistance, float, 0.0f, AM_DEFAULT);
|
|
|
|
|
+ URHO3D_ACCESSOR_ATTRIBUTE("Shadow Distance", GetShadowDistance, SetShadowDistance, float, 0.0f, AM_DEFAULT);
|
|
|
|
|
+ URHO3D_ACCESSOR_ATTRIBUTE("Animation LOD Bias", GetAnimationLodBias, SetAnimationLodBias, float, 1.0f, AM_DEFAULT);
|
|
|
|
|
+ URHO3D_COPY_BASE_ATTRIBUTES(Drawable);
|
|
|
|
|
+ URHO3D_MIXED_ACCESSOR_ATTRIBUTE("Billboards", GetBillboardsAttr, SetBillboardsAttr, VariantVector, Variant::emptyVariantVector,
|
|
|
AM_FILE);
|
|
AM_FILE);
|
|
|
- ACCESSOR_ATTRIBUTE("Network Billboards", GetNetBillboardsAttr, SetNetBillboardsAttr, PODVector<unsigned char>,
|
|
|
|
|
|
|
+ URHO3D_ACCESSOR_ATTRIBUTE("Network Billboards", GetNetBillboardsAttr, SetNetBillboardsAttr, PODVector<unsigned char>,
|
|
|
Variant::emptyBuffer, AM_NET | AM_NOEDIT);
|
|
Variant::emptyBuffer, AM_NET | AM_NOEDIT);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -144,12 +138,14 @@ void BillboardSet::ProcessRayQuery(const RayOctreeQuery& query, PODVector<RayQue
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < billboards_.Size(); ++i)
|
|
for (unsigned i = 0; i < billboards_.Size(); ++i)
|
|
|
{
|
|
{
|
|
|
- if (!billboards_[i]->enabled_)
|
|
|
|
|
|
|
+ if (!billboards_[i].enabled_)
|
|
|
continue;
|
|
continue;
|
|
|
|
|
|
|
|
// Approximate the billboards as spheres for raycasting
|
|
// Approximate the billboards as spheres for raycasting
|
|
|
- float size = INV_SQRT_TWO * (billboards_[i]->size_.x_ * billboardScale.x_ + billboards_[i]->size_.y_ * billboardScale.y_);
|
|
|
|
|
- Vector3 center = billboardTransform * billboards_[i]->position_;
|
|
|
|
|
|
|
+ float size = INV_SQRT_TWO * (billboards_[i].size_.x_ * billboardScale.x_ + billboards_[i].size_.y_ * billboardScale.y_);
|
|
|
|
|
+ if (fixedScreenSize_)
|
|
|
|
|
+ size *= billboards_[i].screenScaleFactor_;
|
|
|
|
|
+ Vector3 center = billboardTransform * billboards_[i].position_;
|
|
|
Sphere billboardSphere(center, size);
|
|
Sphere billboardSphere(center, size);
|
|
|
|
|
|
|
|
float distance = query.ray_.HitDistance(billboardSphere);
|
|
float distance = query.ray_.HitDistance(billboardSphere);
|
|
@@ -180,8 +176,19 @@ void BillboardSet::UpdateBatches(const FrameInfo& frame)
|
|
|
Vector3 worldPos = node_->GetWorldPosition();
|
|
Vector3 worldPos = node_->GetWorldPosition();
|
|
|
Vector3 offset = (worldPos - frame.camera_->GetNode()->GetWorldPosition());
|
|
Vector3 offset = (worldPos - frame.camera_->GetNode()->GetWorldPosition());
|
|
|
// Sort if position relative to camera has changed
|
|
// Sort if position relative to camera has changed
|
|
|
- if (offset != previousOffset_ & sorted_)
|
|
|
|
|
- sortThisFrame_ = true;
|
|
|
|
|
|
|
+ if (offset != previousOffset_ || frame.camera_->IsOrthographic() != hasOrthoCamera_)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (sorted_)
|
|
|
|
|
+ sortThisFrame_ = true;
|
|
|
|
|
+ if (faceCameraMode_ == FC_DIRECTION)
|
|
|
|
|
+ bufferDirty_ = true;
|
|
|
|
|
+
|
|
|
|
|
+ hasOrthoCamera_ = frame.camera_->IsOrthographic();
|
|
|
|
|
+
|
|
|
|
|
+ // Calculate fixed screen size scale factor for billboards if needed
|
|
|
|
|
+ if (fixedScreenSize_)
|
|
|
|
|
+ CalculateFixedScreenSize(frame);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
|
|
distance_ = frame.camera_->GetDistance(GetWorldBoundingBox().Center());
|
|
|
|
|
|
|
@@ -204,11 +211,9 @@ void BillboardSet::UpdateBatches(const FrameInfo& frame)
|
|
|
|
|
|
|
|
void BillboardSet::UpdateGeometry(const FrameInfo& frame)
|
|
void BillboardSet::UpdateGeometry(const FrameInfo& frame)
|
|
|
{
|
|
{
|
|
|
- if (bufferSizeDirty_ || indexBuffer_->IsDataLost())
|
|
|
|
|
- UpdateBufferSize();
|
|
|
|
|
-
|
|
|
|
|
- if (bufferDirty_ || sortThisFrame_ || vertexBuffer_->IsDataLost())
|
|
|
|
|
- UpdateVertexBuffer(frame);
|
|
|
|
|
|
|
+ // If rendering from multiple views and fixed screen size is in use, re-update scale factors before each render
|
|
|
|
|
+ if (fixedScreenSize_ && viewCameras_.Size() > 1)
|
|
|
|
|
+ CalculateFixedScreenSize(frame);
|
|
|
|
|
|
|
|
// If using camera facing, re-update the rotation for the current view now
|
|
// If using camera facing, re-update the rotation for the current view now
|
|
|
if (faceCameraMode_ != FC_NONE)
|
|
if (faceCameraMode_ != FC_NONE)
|
|
@@ -216,15 +221,20 @@ void BillboardSet::UpdateGeometry(const FrameInfo& frame)
|
|
|
transforms_[1] = Matrix3x4(Vector3::ZERO, frame.camera_->GetFaceCameraRotation(node_->GetWorldPosition(),
|
|
transforms_[1] = Matrix3x4(Vector3::ZERO, frame.camera_->GetFaceCameraRotation(node_->GetWorldPosition(),
|
|
|
node_->GetWorldRotation(), faceCameraMode_), Vector3::ONE);
|
|
node_->GetWorldRotation(), faceCameraMode_), Vector3::ONE);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ if (bufferSizeDirty_ || indexBuffer_->IsDataLost())
|
|
|
|
|
+ UpdateBufferSize();
|
|
|
|
|
+
|
|
|
|
|
+ if (bufferDirty_ || sortThisFrame_ || vertexBuffer_->IsDataLost())
|
|
|
|
|
+ UpdateVertexBuffer(frame);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
UpdateGeometryType BillboardSet::GetUpdateGeometryType()
|
|
UpdateGeometryType BillboardSet::GetUpdateGeometryType()
|
|
|
{
|
|
{
|
|
|
// If using camera facing, always need some kind of geometry update, in case the billboard set is rendered from several views
|
|
// If using camera facing, always need some kind of geometry update, in case the billboard set is rendered from several views
|
|
|
- if (bufferDirty_ || bufferSizeDirty_ || vertexBuffer_->IsDataLost() || indexBuffer_->IsDataLost() || sortThisFrame_)
|
|
|
|
|
|
|
+ if (bufferDirty_ || bufferSizeDirty_ || vertexBuffer_->IsDataLost() || indexBuffer_->IsDataLost() || sortThisFrame_ ||
|
|
|
|
|
+ faceCameraMode_ != FC_NONE || fixedScreenSize_)
|
|
|
return UPDATE_MAIN_THREAD;
|
|
return UPDATE_MAIN_THREAD;
|
|
|
- else if (faceCameraMode_ != FC_NONE)
|
|
|
|
|
- return UPDATE_WORKER_THREAD;
|
|
|
|
|
else
|
|
else
|
|
|
return UPDATE_NONE;
|
|
return UPDATE_NONE;
|
|
|
}
|
|
}
|
|
@@ -244,20 +254,22 @@ void BillboardSet::SetNumBillboards(unsigned num)
|
|
|
num = MAX_BILLBOARDS;
|
|
num = MAX_BILLBOARDS;
|
|
|
|
|
|
|
|
unsigned oldNum = billboards_.Size();
|
|
unsigned oldNum = billboards_.Size();
|
|
|
|
|
+ if (num == oldNum)
|
|
|
|
|
+ return;
|
|
|
|
|
|
|
|
billboards_.Resize(num);
|
|
billboards_.Resize(num);
|
|
|
|
|
|
|
|
// Set default values to new billboards
|
|
// Set default values to new billboards
|
|
|
for (unsigned i = oldNum; i < num; ++i)
|
|
for (unsigned i = oldNum; i < num; ++i)
|
|
|
{
|
|
{
|
|
|
- SharedPtr<Billboard> bb(new Billboard());
|
|
|
|
|
- bb->position_ = Vector3::ZERO;
|
|
|
|
|
- bb->size_ = Vector2::ONE;
|
|
|
|
|
- bb->uv_ = Rect::POSITIVE;
|
|
|
|
|
- bb->color_ = Color(1.0f, 1.0f, 1.0f);
|
|
|
|
|
- bb->rotation_ = 0.0f;
|
|
|
|
|
- bb->enabled_ = false;
|
|
|
|
|
- billboards_[i] = bb;
|
|
|
|
|
|
|
+ billboards_[i].position_ = Vector3::ZERO;
|
|
|
|
|
+ billboards_[i].size_ = Vector2::ONE;
|
|
|
|
|
+ billboards_[i].uv_ = Rect::POSITIVE;
|
|
|
|
|
+ billboards_[i].color_ = Color(1.0f, 1.0f, 1.0f);
|
|
|
|
|
+ billboards_[i].rotation_ = 0.0f;
|
|
|
|
|
+ billboards_[i].direction_ = Vector3::UP;
|
|
|
|
|
+ billboards_[i].enabled_ = false;
|
|
|
|
|
+ billboards_[i].screenScaleFactor_ = 1.0f;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bufferSizeDirty_ = true;
|
|
bufferSizeDirty_ = true;
|
|
@@ -282,10 +294,30 @@ void BillboardSet::SetSorted(bool enable)
|
|
|
Commit();
|
|
Commit();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void BillboardSet::SetFixedScreenSize(bool enable)
|
|
|
|
|
+{
|
|
|
|
|
+ fixedScreenSize_ = enable;
|
|
|
|
|
+ Commit();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
void BillboardSet::SetFaceCameraMode(FaceCameraMode mode)
|
|
void BillboardSet::SetFaceCameraMode(FaceCameraMode mode)
|
|
|
{
|
|
{
|
|
|
- faceCameraMode_ = mode;
|
|
|
|
|
- MarkNetworkUpdate();
|
|
|
|
|
|
|
+ if ((faceCameraMode_ != FC_DIRECTION && mode == FC_DIRECTION) || (faceCameraMode_ == FC_DIRECTION && mode != FC_DIRECTION))
|
|
|
|
|
+ {
|
|
|
|
|
+ faceCameraMode_ = mode;
|
|
|
|
|
+ if (faceCameraMode_ == FC_DIRECTION)
|
|
|
|
|
+ batches_[0].geometryType_ = GEOM_DIRBILLBOARD;
|
|
|
|
|
+ else
|
|
|
|
|
+ batches_[0].geometryType_ = GEOM_BILLBOARD;
|
|
|
|
|
+ geometryTypeUpdate_ = true;
|
|
|
|
|
+ bufferSizeDirty_ = true;
|
|
|
|
|
+ Commit();
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ faceCameraMode_ = mode;
|
|
|
|
|
+ MarkNetworkUpdate();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void BillboardSet::SetAnimationLodBias(float bias)
|
|
void BillboardSet::SetAnimationLodBias(float bias)
|
|
@@ -307,7 +339,7 @@ Material* BillboardSet::GetMaterial() const
|
|
|
|
|
|
|
|
Billboard* BillboardSet::GetBillboard(unsigned index)
|
|
Billboard* BillboardSet::GetBillboard(unsigned index)
|
|
|
{
|
|
{
|
|
|
- return index < billboards_.Size() ? billboards_[index] : (Billboard*)0;
|
|
|
|
|
|
|
+ return index < billboards_.Size() ? &billboards_[index] : (Billboard*)0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void BillboardSet::SetMaterialAttr(const ResourceRef& value)
|
|
void BillboardSet::SetMaterialAttr(const ResourceRef& value)
|
|
@@ -322,16 +354,34 @@ void BillboardSet::SetBillboardsAttr(const VariantVector& value)
|
|
|
unsigned numBillboards = index < value.Size() ? value[index++].GetUInt() : 0;
|
|
unsigned numBillboards = index < value.Size() ? value[index++].GetUInt() : 0;
|
|
|
SetNumBillboards(numBillboards);
|
|
SetNumBillboards(numBillboards);
|
|
|
|
|
|
|
|
- for (Vector<SharedPtr<Billboard>>::Iterator i = billboards_.Begin(); i != billboards_.End() && index < value.Size(); ++i)
|
|
|
|
|
|
|
+ // Dealing with old billboard format
|
|
|
|
|
+ if (value.Size() == billboards_.Size() * 6 + 1)
|
|
|
{
|
|
{
|
|
|
- Billboard *bb = i->Get();
|
|
|
|
|
- bb->position_ = value[index++].GetVector3();
|
|
|
|
|
- bb->size_ = value[index++].GetVector2();
|
|
|
|
|
- Vector4 uv = value[index++].GetVector4();
|
|
|
|
|
- bb->uv_ = Rect(uv.x_, uv.y_, uv.z_, uv.w_);
|
|
|
|
|
- bb->color_ = value[index++].GetColor();
|
|
|
|
|
- bb->rotation_ = value[index++].GetFloat();
|
|
|
|
|
- bb->enabled_ = value[index++].GetBool();
|
|
|
|
|
|
|
+ for (PODVector<Billboard>::Iterator i = billboards_.Begin(); i != billboards_.End() && index < value.Size(); ++i)
|
|
|
|
|
+ {
|
|
|
|
|
+ i->position_ = value[index++].GetVector3();
|
|
|
|
|
+ i->size_ = value[index++].GetVector2();
|
|
|
|
|
+ Vector4 uv = value[index++].GetVector4();
|
|
|
|
|
+ i->uv_ = Rect(uv.x_, uv.y_, uv.z_, uv.w_);
|
|
|
|
|
+ i->color_ = value[index++].GetColor();
|
|
|
|
|
+ i->rotation_ = value[index++].GetFloat();
|
|
|
|
|
+ i->enabled_ = value[index++].GetBool();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // New billboard format
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ for (PODVector<Billboard>::Iterator i = billboards_.Begin(); i != billboards_.End() && index < value.Size(); ++i)
|
|
|
|
|
+ {
|
|
|
|
|
+ i->position_ = value[index++].GetVector3();
|
|
|
|
|
+ i->size_ = value[index++].GetVector2();
|
|
|
|
|
+ Vector4 uv = value[index++].GetVector4();
|
|
|
|
|
+ i->uv_ = Rect(uv.x_, uv.y_, uv.z_, uv.w_);
|
|
|
|
|
+ i->color_ = value[index++].GetColor();
|
|
|
|
|
+ i->rotation_ = value[index++].GetFloat();
|
|
|
|
|
+ i->direction_ = value[index++].GetVector3();
|
|
|
|
|
+ i->enabled_ = value[index++].GetBool();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Commit();
|
|
Commit();
|
|
@@ -343,15 +393,15 @@ void BillboardSet::SetNetBillboardsAttr(const PODVector<unsigned char>& value)
|
|
|
unsigned numBillboards = buf.ReadVLE();
|
|
unsigned numBillboards = buf.ReadVLE();
|
|
|
SetNumBillboards(numBillboards);
|
|
SetNumBillboards(numBillboards);
|
|
|
|
|
|
|
|
- for (Vector<SharedPtr<Billboard>>::Iterator i = billboards_.Begin(); i != billboards_.End(); ++i)
|
|
|
|
|
|
|
+ for (PODVector<Billboard>::Iterator i = billboards_.Begin(); i != billboards_.End(); ++i)
|
|
|
{
|
|
{
|
|
|
- Billboard *bb = i->Get();
|
|
|
|
|
- bb->position_ = buf.ReadVector3();
|
|
|
|
|
- bb->size_ = buf.ReadVector2();
|
|
|
|
|
- bb->uv_ = buf.ReadRect();
|
|
|
|
|
- bb->color_ = buf.ReadColor();
|
|
|
|
|
- bb->rotation_ = buf.ReadFloat();
|
|
|
|
|
- bb->enabled_ = buf.ReadBool();
|
|
|
|
|
|
|
+ i->position_ = buf.ReadVector3();
|
|
|
|
|
+ i->size_ = buf.ReadVector2();
|
|
|
|
|
+ i->uv_ = buf.ReadRect();
|
|
|
|
|
+ i->color_ = buf.ReadColor();
|
|
|
|
|
+ i->rotation_ = buf.ReadFloat();
|
|
|
|
|
+ i->direction_ = buf.ReadVector3();
|
|
|
|
|
+ i->enabled_ = buf.ReadBool();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Commit();
|
|
Commit();
|
|
@@ -365,18 +415,18 @@ ResourceRef BillboardSet::GetMaterialAttr() const
|
|
|
VariantVector BillboardSet::GetBillboardsAttr() const
|
|
VariantVector BillboardSet::GetBillboardsAttr() const
|
|
|
{
|
|
{
|
|
|
VariantVector ret;
|
|
VariantVector ret;
|
|
|
- ret.Reserve(billboards_.Size() * 6 + 1);
|
|
|
|
|
|
|
+ ret.Reserve(billboards_.Size() * 7 + 1);
|
|
|
ret.Push(billboards_.Size());
|
|
ret.Push(billboards_.Size());
|
|
|
|
|
|
|
|
- for (Vector<SharedPtr<Billboard>>::ConstIterator i = billboards_.Begin(); i != billboards_.End(); ++i)
|
|
|
|
|
|
|
+ for (PODVector<Billboard>::ConstIterator i = billboards_.Begin(); i != billboards_.End(); ++i)
|
|
|
{
|
|
{
|
|
|
- Billboard *bb = i->Get();
|
|
|
|
|
- ret.Push(bb->position_);
|
|
|
|
|
- ret.Push(bb->size_);
|
|
|
|
|
- ret.Push(Vector4(bb->uv_.min_.x_, bb->uv_.min_.y_, bb->uv_.max_.x_, bb->uv_.max_.y_));
|
|
|
|
|
- ret.Push(bb->color_);
|
|
|
|
|
- ret.Push(bb->rotation_);
|
|
|
|
|
- ret.Push(bb->enabled_);
|
|
|
|
|
|
|
+ ret.Push(i->position_);
|
|
|
|
|
+ ret.Push(i->size_);
|
|
|
|
|
+ ret.Push(Vector4(i->uv_.min_.x_, i->uv_.min_.y_, i->uv_.max_.x_, i->uv_.max_.y_));
|
|
|
|
|
+ ret.Push(i->color_);
|
|
|
|
|
+ ret.Push(i->rotation_);
|
|
|
|
|
+ ret.Push(i->direction_);
|
|
|
|
|
+ ret.Push(i->enabled_);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
@@ -387,15 +437,15 @@ const PODVector<unsigned char>& BillboardSet::GetNetBillboardsAttr() const
|
|
|
attrBuffer_.Clear();
|
|
attrBuffer_.Clear();
|
|
|
attrBuffer_.WriteVLE(billboards_.Size());
|
|
attrBuffer_.WriteVLE(billboards_.Size());
|
|
|
|
|
|
|
|
- for (Vector<SharedPtr<Billboard>>::ConstIterator i = billboards_.Begin(); i != billboards_.End(); ++i)
|
|
|
|
|
|
|
+ for (PODVector<Billboard>::ConstIterator i = billboards_.Begin(); i != billboards_.End(); ++i)
|
|
|
{
|
|
{
|
|
|
- Billboard *bb = i->Get();
|
|
|
|
|
- attrBuffer_.WriteVector3(bb->position_);
|
|
|
|
|
- attrBuffer_.WriteVector2(bb->size_);
|
|
|
|
|
- attrBuffer_.WriteRect(bb->uv_);
|
|
|
|
|
- attrBuffer_.WriteColor(bb->color_);
|
|
|
|
|
- attrBuffer_.WriteFloat(bb->rotation_);
|
|
|
|
|
- attrBuffer_.WriteBool(bb->enabled_);
|
|
|
|
|
|
|
+ attrBuffer_.WriteVector3(i->position_);
|
|
|
|
|
+ attrBuffer_.WriteVector2(i->size_);
|
|
|
|
|
+ attrBuffer_.WriteRect(i->uv_);
|
|
|
|
|
+ attrBuffer_.WriteColor(i->color_);
|
|
|
|
|
+ attrBuffer_.WriteFloat(i->rotation_);
|
|
|
|
|
+ attrBuffer_.WriteVector3(i->direction_);
|
|
|
|
|
+ attrBuffer_.WriteBool(i->enabled_);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return attrBuffer_.GetBuffer();
|
|
return attrBuffer_.GetBuffer();
|
|
@@ -411,11 +461,14 @@ void BillboardSet::OnWorldBoundingBoxUpdate()
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < billboards_.Size(); ++i)
|
|
for (unsigned i = 0; i < billboards_.Size(); ++i)
|
|
|
{
|
|
{
|
|
|
- if (!billboards_[i]->enabled_)
|
|
|
|
|
|
|
+ if (!billboards_[i].enabled_)
|
|
|
continue;
|
|
continue;
|
|
|
|
|
|
|
|
- float size = INV_SQRT_TWO * (billboards_[i]->size_.x_ * billboardScale.x_ + billboards_[i]->size_.y_ * billboardScale.y_);
|
|
|
|
|
- Vector3 center = billboardTransform * billboards_[i]->position_;
|
|
|
|
|
|
|
+ float size = INV_SQRT_TWO * (billboards_[i].size_.x_ * billboardScale.x_ + billboards_[i].size_.y_ * billboardScale.y_);
|
|
|
|
|
+ if (fixedScreenSize_)
|
|
|
|
|
+ size *= billboards_[i].screenScaleFactor_;
|
|
|
|
|
+
|
|
|
|
|
+ Vector3 center = billboardTransform * billboards_[i].position_;
|
|
|
Vector3 edge = Vector3::ONE * size;
|
|
Vector3 edge = Vector3::ONE * size;
|
|
|
worldBox.Merge(BoundingBox(center - edge, center + edge));
|
|
worldBox.Merge(BoundingBox(center - edge, center + edge));
|
|
|
|
|
|
|
@@ -432,8 +485,21 @@ void BillboardSet::UpdateBufferSize()
|
|
|
{
|
|
{
|
|
|
unsigned numBillboards = billboards_.Size();
|
|
unsigned numBillboards = billboards_.Size();
|
|
|
|
|
|
|
|
- if (vertexBuffer_->GetVertexCount() != numBillboards * 4)
|
|
|
|
|
- vertexBuffer_->SetSize(numBillboards * 4, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1 | MASK_TEXCOORD2, true);
|
|
|
|
|
|
|
+ if (vertexBuffer_->GetVertexCount() != numBillboards * 4 || geometryTypeUpdate_)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (faceCameraMode_ == FC_DIRECTION)
|
|
|
|
|
+ {
|
|
|
|
|
+ vertexBuffer_->SetSize(numBillboards * 4, MASK_POSITION | MASK_NORMAL | MASK_COLOR | MASK_TEXCOORD1 | MASK_TEXCOORD2, true);
|
|
|
|
|
+ geometry_->SetVertexBuffer(0, vertexBuffer_);
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ vertexBuffer_->SetSize(numBillboards * 4, MASK_POSITION | MASK_COLOR | MASK_TEXCOORD1 | MASK_TEXCOORD2, true);
|
|
|
|
|
+ geometry_->SetVertexBuffer(0, vertexBuffer_);
|
|
|
|
|
+ }
|
|
|
|
|
+ geometryTypeUpdate_ = false;
|
|
|
|
|
+ }
|
|
|
if (indexBuffer_->GetIndexCount() != numBillboards * 6)
|
|
if (indexBuffer_->GetIndexCount() != numBillboards * 6)
|
|
|
indexBuffer_->SetSize(numBillboards * 6, false);
|
|
indexBuffer_->SetSize(numBillboards * 6, false);
|
|
|
|
|
|
|
@@ -492,7 +558,7 @@ void BillboardSet::UpdateVertexBuffer(const FrameInfo& frame)
|
|
|
// First check number of enabled billboards
|
|
// First check number of enabled billboards
|
|
|
for (unsigned i = 0; i < numBillboards; ++i)
|
|
for (unsigned i = 0; i < numBillboards; ++i)
|
|
|
{
|
|
{
|
|
|
- if (billboards_[i]->enabled_)
|
|
|
|
|
|
|
+ if (billboards_[i].enabled_)
|
|
|
++enabledBillboards;
|
|
++enabledBillboards;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -502,12 +568,12 @@ void BillboardSet::UpdateVertexBuffer(const FrameInfo& frame)
|
|
|
// Then set initial sort order and distances
|
|
// Then set initial sort order and distances
|
|
|
for (unsigned i = 0; i < numBillboards; ++i)
|
|
for (unsigned i = 0; i < numBillboards; ++i)
|
|
|
{
|
|
{
|
|
|
- SharedPtr<Billboard> billboard = billboards_[i];
|
|
|
|
|
- if (billboard->enabled_)
|
|
|
|
|
|
|
+ Billboard& billboard = billboards_[i];
|
|
|
|
|
+ if (billboard.enabled_)
|
|
|
{
|
|
{
|
|
|
- sortedBillboards_[index++] = billboard;
|
|
|
|
|
|
|
+ sortedBillboards_[index++] = &billboard;
|
|
|
if (sorted_)
|
|
if (sorted_)
|
|
|
- billboard->sortDistance_ = frame.camera_->GetDistanceSquared(billboardTransform * billboards_[i]->position_);
|
|
|
|
|
|
|
+ billboard.sortDistance_ = frame.camera_->GetDistanceSquared(billboardTransform * billboards_[i].position_);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -530,56 +596,127 @@ void BillboardSet::UpdateVertexBuffer(const FrameInfo& frame)
|
|
|
if (!dest)
|
|
if (!dest)
|
|
|
return;
|
|
return;
|
|
|
|
|
|
|
|
- for (unsigned i = 0; i < enabledBillboards; ++i)
|
|
|
|
|
|
|
+ if (faceCameraMode_ != FC_DIRECTION)
|
|
|
|
|
+ {
|
|
|
|
|
+ for (unsigned i = 0; i < enabledBillboards; ++i)
|
|
|
|
|
+ {
|
|
|
|
|
+ Billboard& billboard = *sortedBillboards_[i];
|
|
|
|
|
+
|
|
|
|
|
+ Vector2 size(billboard.size_.x_ * billboardScale.x_, billboard.size_.y_ * billboardScale.y_);
|
|
|
|
|
+ unsigned color = billboard.color_.ToUInt();
|
|
|
|
|
+ if (fixedScreenSize_)
|
|
|
|
|
+ size *= billboard.screenScaleFactor_;
|
|
|
|
|
+
|
|
|
|
|
+ float rotationMatrix[2][2];
|
|
|
|
|
+ SinCos(billboard.rotation_, rotationMatrix[0][1], rotationMatrix[0][0]);
|
|
|
|
|
+ rotationMatrix[1][0] = -rotationMatrix[0][1];
|
|
|
|
|
+ rotationMatrix[1][1] = rotationMatrix[0][0];
|
|
|
|
|
+
|
|
|
|
|
+ dest[0] = billboard.position_.x_;
|
|
|
|
|
+ dest[1] = billboard.position_.y_;
|
|
|
|
|
+ dest[2] = billboard.position_.z_;
|
|
|
|
|
+ ((unsigned&)dest[3]) = color;
|
|
|
|
|
+ dest[4] = billboard.uv_.min_.x_;
|
|
|
|
|
+ dest[5] = billboard.uv_.min_.y_;
|
|
|
|
|
+ dest[6] = -size.x_ * rotationMatrix[0][0] + size.y_ * rotationMatrix[0][1];
|
|
|
|
|
+ dest[7] = -size.x_ * rotationMatrix[1][0] + size.y_ * rotationMatrix[1][1];
|
|
|
|
|
+
|
|
|
|
|
+ dest[8] = billboard.position_.x_;
|
|
|
|
|
+ dest[9] = billboard.position_.y_;
|
|
|
|
|
+ dest[10] = billboard.position_.z_;
|
|
|
|
|
+ ((unsigned&)dest[11]) = color;
|
|
|
|
|
+ dest[12] = billboard.uv_.max_.x_;
|
|
|
|
|
+ dest[13] = billboard.uv_.min_.y_;
|
|
|
|
|
+ dest[14] = size.x_ * rotationMatrix[0][0] + size.y_ * rotationMatrix[0][1];
|
|
|
|
|
+ dest[15] = size.x_ * rotationMatrix[1][0] + size.y_ * rotationMatrix[1][1];
|
|
|
|
|
+
|
|
|
|
|
+ dest[16] = billboard.position_.x_;
|
|
|
|
|
+ dest[17] = billboard.position_.y_;
|
|
|
|
|
+ dest[18] = billboard.position_.z_;
|
|
|
|
|
+ ((unsigned&)dest[19]) = color;
|
|
|
|
|
+ dest[20] = billboard.uv_.max_.x_;
|
|
|
|
|
+ dest[21] = billboard.uv_.max_.y_;
|
|
|
|
|
+ dest[22] = size.x_ * rotationMatrix[0][0] - size.y_ * rotationMatrix[0][1];
|
|
|
|
|
+ dest[23] = size.x_ * rotationMatrix[1][0] - size.y_ * rotationMatrix[1][1];
|
|
|
|
|
+
|
|
|
|
|
+ dest[24] = billboard.position_.x_;
|
|
|
|
|
+ dest[25] = billboard.position_.y_;
|
|
|
|
|
+ dest[26] = billboard.position_.z_;
|
|
|
|
|
+ ((unsigned&)dest[27]) = color;
|
|
|
|
|
+ dest[28] = billboard.uv_.min_.x_;
|
|
|
|
|
+ dest[29] = billboard.uv_.max_.y_;
|
|
|
|
|
+ dest[30] = -size.x_ * rotationMatrix[0][0] - size.y_ * rotationMatrix[0][1];
|
|
|
|
|
+ dest[31] = -size.x_ * rotationMatrix[1][0] - size.y_ * rotationMatrix[1][1];
|
|
|
|
|
+
|
|
|
|
|
+ dest += 32;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
{
|
|
{
|
|
|
- Billboard& billboard = *sortedBillboards_[i];
|
|
|
|
|
-
|
|
|
|
|
- Vector2 size(billboard.size_.x_ * billboardScale.x_, billboard.size_.y_ * billboardScale.y_);
|
|
|
|
|
- unsigned color = billboard.color_.ToUInt();
|
|
|
|
|
-
|
|
|
|
|
- float rotationMatrix[2][2];
|
|
|
|
|
- rotationMatrix[0][0] = Cos(billboard.rotation_);
|
|
|
|
|
- rotationMatrix[0][1] = Sin(billboard.rotation_);
|
|
|
|
|
- rotationMatrix[1][0] = -rotationMatrix[0][1];
|
|
|
|
|
- rotationMatrix[1][1] = rotationMatrix[0][0];
|
|
|
|
|
-
|
|
|
|
|
- dest[0] = billboard.position_.x_;
|
|
|
|
|
- dest[1] = billboard.position_.y_;
|
|
|
|
|
- dest[2] = billboard.position_.z_;
|
|
|
|
|
- ((unsigned&)dest[3]) = color;
|
|
|
|
|
- dest[4] = billboard.uv_.min_.x_;
|
|
|
|
|
- dest[5] = billboard.uv_.min_.y_;
|
|
|
|
|
- dest[6] = -size.x_ * rotationMatrix[0][0] + size.y_ * rotationMatrix[0][1];
|
|
|
|
|
- dest[7] = -size.x_ * rotationMatrix[1][0] + size.y_ * rotationMatrix[1][1];
|
|
|
|
|
-
|
|
|
|
|
- dest[8] = billboard.position_.x_;
|
|
|
|
|
- dest[9] = billboard.position_.y_;
|
|
|
|
|
- dest[10] = billboard.position_.z_;
|
|
|
|
|
- ((unsigned&)dest[11]) = color;
|
|
|
|
|
- dest[12] = billboard.uv_.max_.x_;
|
|
|
|
|
- dest[13] = billboard.uv_.min_.y_;
|
|
|
|
|
- dest[14] = size.x_ * rotationMatrix[0][0] + size.y_ * rotationMatrix[0][1];
|
|
|
|
|
- dest[15] = size.x_ * rotationMatrix[1][0] + size.y_ * rotationMatrix[1][1];
|
|
|
|
|
-
|
|
|
|
|
- dest[16] = billboard.position_.x_;
|
|
|
|
|
- dest[17] = billboard.position_.y_;
|
|
|
|
|
- dest[18] = billboard.position_.z_;
|
|
|
|
|
- ((unsigned&)dest[19]) = color;
|
|
|
|
|
- dest[20] = billboard.uv_.max_.x_;
|
|
|
|
|
- dest[21] = billboard.uv_.max_.y_;
|
|
|
|
|
- dest[22] = size.x_ * rotationMatrix[0][0] - size.y_ * rotationMatrix[0][1];
|
|
|
|
|
- dest[23] = size.x_ * rotationMatrix[1][0] - size.y_ * rotationMatrix[1][1];
|
|
|
|
|
-
|
|
|
|
|
- dest[24] = billboard.position_.x_;
|
|
|
|
|
- dest[25] = billboard.position_.y_;
|
|
|
|
|
- dest[26] = billboard.position_.z_;
|
|
|
|
|
- ((unsigned&)dest[27]) = color;
|
|
|
|
|
- dest[28] = billboard.uv_.min_.x_;
|
|
|
|
|
- dest[29] = billboard.uv_.max_.y_;
|
|
|
|
|
- dest[30] = -size.x_ * rotationMatrix[0][0] - size.y_ * rotationMatrix[0][1];
|
|
|
|
|
- dest[31] = -size.x_ * rotationMatrix[1][0] - size.y_ * rotationMatrix[1][1];
|
|
|
|
|
-
|
|
|
|
|
- dest += 32;
|
|
|
|
|
|
|
+ for (unsigned i = 0; i < enabledBillboards; ++i)
|
|
|
|
|
+ {
|
|
|
|
|
+ Billboard& billboard = *sortedBillboards_[i];
|
|
|
|
|
+
|
|
|
|
|
+ Vector2 size(billboard.size_.x_ * billboardScale.x_, billboard.size_.y_ * billboardScale.y_);
|
|
|
|
|
+ unsigned color = billboard.color_.ToUInt();
|
|
|
|
|
+ if (fixedScreenSize_)
|
|
|
|
|
+ size *= billboard.screenScaleFactor_;
|
|
|
|
|
+
|
|
|
|
|
+ float rot2D[2][2];
|
|
|
|
|
+ SinCos(billboard.rotation_, rot2D[0][1], rot2D[0][0]);
|
|
|
|
|
+ rot2D[1][0] = -rot2D[0][1];
|
|
|
|
|
+ rot2D[1][1] = rot2D[0][0];
|
|
|
|
|
+
|
|
|
|
|
+ dest[0] = billboard.position_.x_;
|
|
|
|
|
+ dest[1] = billboard.position_.y_;
|
|
|
|
|
+ dest[2] = billboard.position_.z_;
|
|
|
|
|
+ dest[3] = billboard.direction_.x_;
|
|
|
|
|
+ dest[4] = billboard.direction_.y_;
|
|
|
|
|
+ dest[5] = billboard.direction_.z_;
|
|
|
|
|
+ ((unsigned&)dest[6]) = color;
|
|
|
|
|
+ dest[7] = billboard.uv_.min_.x_;
|
|
|
|
|
+ dest[8] = billboard.uv_.min_.y_;
|
|
|
|
|
+ dest[9] = -size.x_ * rot2D[0][0] + size.y_ * rot2D[0][1];
|
|
|
|
|
+ dest[10] = -size.x_ * rot2D[1][0] + size.y_ * rot2D[1][1];
|
|
|
|
|
+
|
|
|
|
|
+ dest[11] = billboard.position_.x_;
|
|
|
|
|
+ dest[12] = billboard.position_.y_;
|
|
|
|
|
+ dest[13] = billboard.position_.z_;
|
|
|
|
|
+ dest[14] = billboard.direction_.x_;
|
|
|
|
|
+ dest[15] = billboard.direction_.y_;
|
|
|
|
|
+ dest[16] = billboard.direction_.z_;
|
|
|
|
|
+ ((unsigned&)dest[17]) = color;
|
|
|
|
|
+ dest[18] = billboard.uv_.max_.x_;
|
|
|
|
|
+ dest[19] = billboard.uv_.min_.y_;
|
|
|
|
|
+ dest[20] = size.x_ * rot2D[0][0] + size.y_ * rot2D[0][1];
|
|
|
|
|
+ dest[21] = size.x_ * rot2D[1][0] + size.y_ * rot2D[1][1];
|
|
|
|
|
+
|
|
|
|
|
+ dest[22] = billboard.position_.x_;
|
|
|
|
|
+ dest[23] = billboard.position_.y_;
|
|
|
|
|
+ dest[24] = billboard.position_.z_;
|
|
|
|
|
+ dest[25] = billboard.direction_.x_;
|
|
|
|
|
+ dest[26] = billboard.direction_.y_;
|
|
|
|
|
+ dest[27] = billboard.direction_.z_;
|
|
|
|
|
+ ((unsigned&)dest[28]) = color;
|
|
|
|
|
+ dest[29] = billboard.uv_.max_.x_;
|
|
|
|
|
+ dest[30] = billboard.uv_.max_.y_;
|
|
|
|
|
+ dest[31] = size.x_ * rot2D[0][0] - size.y_ * rot2D[0][1];
|
|
|
|
|
+ dest[32] = size.x_ * rot2D[1][0] - size.y_ * rot2D[1][1];
|
|
|
|
|
+
|
|
|
|
|
+ dest[33] = billboard.position_.x_;
|
|
|
|
|
+ dest[34] = billboard.position_.y_;
|
|
|
|
|
+ dest[35] = billboard.position_.z_;
|
|
|
|
|
+ dest[36] = billboard.direction_.x_;
|
|
|
|
|
+ dest[37] = billboard.direction_.y_;
|
|
|
|
|
+ dest[38] = billboard.direction_.z_;
|
|
|
|
|
+ ((unsigned&)dest[39]) = color;
|
|
|
|
|
+ dest[40] = billboard.uv_.min_.x_;
|
|
|
|
|
+ dest[41] = billboard.uv_.max_.y_;
|
|
|
|
|
+ dest[42] = -size.x_ * rot2D[0][0] - size.y_ * rot2D[0][1];
|
|
|
|
|
+ dest[43] = -size.x_ * rot2D[1][0] - size.y_ * rot2D[1][1];
|
|
|
|
|
+
|
|
|
|
|
+ dest += 44;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
vertexBuffer_->Unlock();
|
|
vertexBuffer_->Unlock();
|
|
@@ -592,4 +729,32 @@ void BillboardSet::MarkPositionsDirty()
|
|
|
bufferDirty_ = true;
|
|
bufferDirty_ = true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void BillboardSet::CalculateFixedScreenSize(const FrameInfo& frame)
|
|
|
|
|
+{
|
|
|
|
|
+ float invViewHeight = 1.0f / frame.viewSize_.y_;
|
|
|
|
|
+ float halfViewWorldSize = frame.camera_->GetHalfViewSize();
|
|
|
|
|
+
|
|
|
|
|
+ if (!frame.camera_->IsOrthographic())
|
|
|
|
|
+ {
|
|
|
|
|
+ Matrix4 viewProj(frame.camera_->GetProjection(false) * frame.camera_->GetView());
|
|
|
|
|
+ const Matrix3x4& worldTransform = node_->GetWorldTransform();
|
|
|
|
|
+ Matrix3x4 billboardTransform = relative_ ? worldTransform : Matrix3x4::IDENTITY;
|
|
|
|
|
+
|
|
|
|
|
+ for (unsigned i = 0; i < billboards_.Size(); ++i)
|
|
|
|
|
+ {
|
|
|
|
|
+ Vector4 projPos(viewProj * Vector4(billboardTransform * billboards_[i].position_, 1.0f));
|
|
|
|
|
+ billboards_[i].screenScaleFactor_ = invViewHeight * halfViewWorldSize * projPos.w_;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ for (unsigned i = 0; i < billboards_.Size(); ++i)
|
|
|
|
|
+ billboards_[i].screenScaleFactor_ = invViewHeight * halfViewWorldSize;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ bufferDirty_ = true;
|
|
|
|
|
+ forceUpdate_ = true;
|
|
|
|
|
+ worldBoundingBoxDirty_ = true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
}
|
|
}
|