Merge remote-tracking branch 'origin/dev_item_normal' into dev
This commit is contained in:
commit
ec7216361d
@ -74,10 +74,13 @@ void ItemState::setDisappearCounter()
|
||||
// -----------------------------------------------------------------------
|
||||
/** Initialises an item.
|
||||
* \param type Type for this item.
|
||||
* \param xyz The position for this item.
|
||||
* \param normal The normal for this item.
|
||||
*/
|
||||
void ItemState::initItem(ItemType type, const Vec3& xyz)
|
||||
void ItemState::initItem(ItemType type, const Vec3& xyz, const Vec3& normal)
|
||||
{
|
||||
m_xyz = xyz;
|
||||
m_normal = normal;
|
||||
m_original_type = ITEM_NONE;
|
||||
m_ticks_till_return = 0;
|
||||
setDisappearCounter();
|
||||
@ -156,7 +159,7 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
|
||||
|
||||
m_was_available_previously = true;
|
||||
m_distance_2 = 1.2f;
|
||||
initItem(type, xyz);
|
||||
initItem(type, xyz, normal);
|
||||
m_graphical_type = type;
|
||||
m_original_rotation = shortestArcQuat(Vec3(0, 1, 0), normal);
|
||||
m_listener = NULL;
|
||||
@ -206,7 +209,7 @@ Item::Item(const Vec3& xyz, float distance, TriggerItemListener* trigger)
|
||||
: ItemState(ITEM_TRIGGER)
|
||||
{
|
||||
m_distance_2 = distance*distance;
|
||||
initItem(ITEM_TRIGGER, xyz);
|
||||
initItem(ITEM_TRIGGER, xyz, /*normal not required*/Vec3(0,0,0));
|
||||
m_graphical_type = ITEM_TRIGGER;
|
||||
m_original_rotation = btQuaternion(0, 0, 0, 1);
|
||||
m_node = NULL;
|
||||
@ -218,10 +221,12 @@ Item::Item(const Vec3& xyz, float distance, TriggerItemListener* trigger)
|
||||
/** Initialises the item. Note that m_distance_2 must be defined before calling
|
||||
* this function, since it pre-computes some values based on this.
|
||||
* \param type Type of the item.
|
||||
* \param xyz Position of this item.
|
||||
* \param normal Normal for this item.
|
||||
*/
|
||||
void Item::initItem(ItemType type, const Vec3 &xyz)
|
||||
void Item::initItem(ItemType type, const Vec3 &xyz, const Vec3&normal)
|
||||
{
|
||||
ItemState::initItem(type, xyz);
|
||||
ItemState::initItem(type, xyz, normal);
|
||||
// Now determine in which quad this item is, and its distance
|
||||
// from the center within this quad.
|
||||
m_graph_node = Graph::UNKNOWN_SECTOR;
|
||||
|
@ -119,10 +119,17 @@ private:
|
||||
* will always reappear after a while. */
|
||||
int m_used_up_counter;
|
||||
|
||||
/** The original position - saves calls to m_node->getPosition()
|
||||
* and then converting this value to a Vec3. */
|
||||
/** The position of this ItemState. */
|
||||
Vec3 m_xyz;
|
||||
|
||||
/** The original rotation of the item. While this is technically a visual
|
||||
* only value (atm, it could be used for collision detection), it is
|
||||
* required to make sure a client can display items with the right normal
|
||||
* (in case that a client would get a different (or no) normal from a
|
||||
* raycast).
|
||||
*/
|
||||
Vec3 m_normal;
|
||||
|
||||
/** The 'owner' of the item, i.e. the kart that dropped this item.
|
||||
* Is NULL if the item is part of the track. */
|
||||
const AbstractKart *m_previous_owner;
|
||||
@ -154,7 +161,7 @@ protected:
|
||||
|
||||
public:
|
||||
ItemState(ItemType type, const AbstractKart *owner=NULL, int id = -1);
|
||||
void initItem(ItemType type, const Vec3& xyz);
|
||||
void initItem(ItemType type, const Vec3& xyz, const Vec3& normal);
|
||||
void update(int ticks);
|
||||
void setDisappearCounter();
|
||||
virtual void collected(const AbstractKart *kart);
|
||||
@ -305,6 +312,12 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the XYZ position of the item. */
|
||||
const Vec3& getXYZ() const { return m_xyz; }
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the normal of the ItemState. */
|
||||
const Vec3 getNormal() const
|
||||
{
|
||||
return m_normal;
|
||||
}
|
||||
}; // class ItemState
|
||||
|
||||
// ============================================================================
|
||||
@ -350,7 +363,7 @@ private:
|
||||
* would not be collected. Used by the AI to avoid items. */
|
||||
Vec3 *m_avoidance_points[2];
|
||||
|
||||
void initItem(ItemType type, const Vec3 &xyz);
|
||||
void initItem(ItemType type, const Vec3 &xyz, const Vec3 &normal);
|
||||
void setMesh(scene::IMesh* mesh, scene::IMesh* lowres_mesh);
|
||||
void handleNewMesh(ItemType type);
|
||||
|
||||
@ -432,6 +445,12 @@ public:
|
||||
return m_avoidance_points[1];
|
||||
} // getAvoidancePoint
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the normal of the item. */
|
||||
const Vec3 getNormal() const
|
||||
{
|
||||
return quatRotate(m_original_rotation, Vec3(0,1,0));
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
scene::ISceneNode *getSceneNode()
|
||||
{
|
||||
|
@ -43,7 +43,8 @@ ItemEventInfo::ItemEventInfo(BareNetworkString *buffer, int *count)
|
||||
if (m_type == IEI_NEW)
|
||||
{
|
||||
m_xyz = buffer->getVec3();
|
||||
*count -= 12;
|
||||
m_normal = buffer->getVec3();
|
||||
*count -= 24;
|
||||
}
|
||||
else // IEI_COLLECT
|
||||
{
|
||||
@ -71,7 +72,10 @@ void ItemEventInfo::saveState(BareNetworkString *buffer)
|
||||
// Only new item and collecting items need the index and kart id:
|
||||
buffer->addUInt8(m_kart_id).addUInt16(m_index);
|
||||
if (m_type == IEI_NEW)
|
||||
{
|
||||
buffer->add(m_xyz);
|
||||
buffer->add(m_normal);
|
||||
}
|
||||
else if (m_type == IEI_COLLECT)
|
||||
buffer->addUInt16(m_ticks_till_return);
|
||||
}
|
||||
|
@ -52,6 +52,9 @@ private:
|
||||
/** In case of new items the position of the new item. */
|
||||
Vec3 m_xyz;
|
||||
|
||||
/** The normal of an item. */
|
||||
Vec3 m_normal;
|
||||
|
||||
/** Ticks for the item to return, atm used by collecting banana
|
||||
* with bomb to delay the return for banana. */
|
||||
int16_t m_ticks_till_return;
|
||||
@ -76,9 +79,9 @@ public:
|
||||
* need to encode the new item type.
|
||||
*/
|
||||
ItemEventInfo(int ticks, ItemState::ItemType type, int index,
|
||||
int kart_id, const Vec3 &xyz)
|
||||
int kart_id, const Vec3 &xyz, const Vec3 &normal)
|
||||
: m_ticks(ticks), m_index(index), m_kart_id(kart_id), m_xyz(xyz),
|
||||
m_ticks_till_return(0)
|
||||
m_normal(normal), m_ticks_till_return(0)
|
||||
{
|
||||
m_type = IEI_NEW;
|
||||
} // ItemEventInfo(new item)
|
||||
@ -125,6 +128,13 @@ public:
|
||||
return m_xyz;
|
||||
} // getXYZ
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns the normal of a new item only. */
|
||||
const Vec3& getNormal() const
|
||||
{
|
||||
assert(isNewItem());
|
||||
return m_normal;
|
||||
} // getNormal
|
||||
// --------------------------------------------------------------------
|
||||
/** Returns the ticks till return, used only by collection events. */
|
||||
int getTicksTillReturn() const { return m_ticks_till_return; }
|
||||
// --------------------------------------------------------------------
|
||||
|
@ -257,42 +257,43 @@ unsigned int ItemManager::insertItem(Item *item)
|
||||
* bubblegum).
|
||||
* \param type Type of the item.
|
||||
* \param kart The kart that drops the new item.
|
||||
* \param xyz Can be used to overwrite the item location (used in networking).
|
||||
* \param server_xyz Can be used to overwrite the item location.
|
||||
* \param server_normal The normal as seen on the server.
|
||||
*/
|
||||
Item* ItemManager::dropNewItem(ItemState::ItemType type,
|
||||
const AbstractKart *kart, const Vec3 *xyz)
|
||||
const AbstractKart *kart,
|
||||
const Vec3 *server_xyz,
|
||||
const Vec3 *server_normal)
|
||||
{
|
||||
Vec3 hit_point;
|
||||
Vec3 normal;
|
||||
if(NetworkConfig::get()->isClient() && !server_xyz) return NULL;
|
||||
Vec3 normal, pos;
|
||||
const Material* material_hit;
|
||||
Vec3 pos = xyz ? *xyz : kart->getXYZ();
|
||||
Vec3 to = pos + kart->getTrans().getBasis() * Vec3(0, -10000, 0);
|
||||
Track::getCurrentTrack()->getTriangleMesh().castRay(pos, to,
|
||||
&hit_point,
|
||||
&material_hit,
|
||||
&normal);
|
||||
|
||||
// We will get no material if the kart is 'over nothing' when dropping
|
||||
// the bubble gum. In most cases this means that the item does not need
|
||||
// to be created (and we just return NULL). Only exception: if the server
|
||||
// has sent a 'new item' event (which means its raycast found terrain),
|
||||
// but the client does not have found a terrain (e.g. differences in
|
||||
// position or more likely floating point differences). In this case, we
|
||||
// must use the server position. In this and only this case xyz is not
|
||||
// NULL (and then contains the server's position for the item).
|
||||
if (!material_hit && !xyz) return NULL;
|
||||
|
||||
if (!material_hit)
|
||||
if (!server_xyz)
|
||||
{
|
||||
// We are on a client which has received a new item event. Still
|
||||
// create this item
|
||||
normal.setValue(0, 1, 0); // Arbitrary, we don't have a normal
|
||||
pos = *xyz;
|
||||
// We are doing a new drop locally, i.e. not based on
|
||||
// server data. So we need a raycast to find the correct
|
||||
// location and normal of the item:
|
||||
pos = server_xyz ? *server_xyz : kart->getXYZ();
|
||||
Vec3 to = pos + kart->getTrans().getBasis() * Vec3(0, -10000, 0);
|
||||
Vec3 hit_point;
|
||||
Track::getCurrentTrack()->getTriangleMesh().castRay(pos, to,
|
||||
&hit_point,
|
||||
&material_hit,
|
||||
&normal);
|
||||
|
||||
// We will get no material if the kart is 'over nothing' when dropping
|
||||
// the bubble gum. In most cases this means that the item does not need
|
||||
// to be created (and we just return NULL).
|
||||
if (!material_hit) return NULL;
|
||||
normal.normalize();
|
||||
pos = hit_point + kart->getTrans().getBasis() * Vec3(0, -0.05f, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
normal.normalize();
|
||||
pos = hit_point + kart->getTrans().getBasis() * Vec3(0, -0.05f, 0);
|
||||
// We are on a client which has received a new item event from the
|
||||
// server. So use the server's data for the new item:
|
||||
normal = *server_normal;
|
||||
pos = *server_xyz;
|
||||
}
|
||||
|
||||
ItemState::ItemType mesh_type = type;
|
||||
|
@ -133,7 +133,9 @@ public:
|
||||
virtual Item* placeItem (ItemState::ItemType type, const Vec3& xyz,
|
||||
const Vec3 &normal);
|
||||
virtual Item* dropNewItem (ItemState::ItemType type,
|
||||
const AbstractKart* parent, const Vec3 *xyz=NULL);
|
||||
const AbstractKart* parent,
|
||||
const Vec3 *server_xyz = NULL,
|
||||
const Vec3 *normal = NULL);
|
||||
virtual Item* placeTrigger (const Vec3& xyz, float distance,
|
||||
TriggerItemListener* listener);
|
||||
void update (int ticks);
|
||||
|
@ -148,23 +148,29 @@ void NetworkItemManager::switchItems()
|
||||
* \param type Type of the item.
|
||||
* \param kart In case of a dropped item used to avoid that a kart
|
||||
* is affected by its own items.
|
||||
* \param server_xyz In case of rewind the server's position of this item.
|
||||
* \param server_normal In case of rewind the server's normal of this item.
|
||||
*/
|
||||
Item* NetworkItemManager::dropNewItem(ItemState::ItemType type,
|
||||
const AbstractKart *kart, const Vec3 *xyz)
|
||||
const AbstractKart *kart,
|
||||
const Vec3 *server_xyz,
|
||||
const Vec3 *server_normal)
|
||||
{
|
||||
Item *item = ItemManager::dropNewItem(type, kart, xyz);
|
||||
Item *item = ItemManager::dropNewItem(type, kart, server_xyz, server_normal);
|
||||
|
||||
if(!item) return NULL;
|
||||
|
||||
// Nothing else to do for client
|
||||
if (NetworkConfig::get()->isClient()) return item;
|
||||
|
||||
assert(!server_xyz);
|
||||
// Server: store the data for this event:
|
||||
m_item_events.lock();
|
||||
m_item_events.getData().emplace_back(World::getWorld()->getTicksSinceStart(),
|
||||
type, item->getItemId(),
|
||||
kart->getWorldKartId(),
|
||||
xyz ? *xyz : kart->getXYZ() );
|
||||
item->getXYZ(),
|
||||
item->getNormal());
|
||||
m_item_events.unlock();
|
||||
return item;
|
||||
} // dropNewItem
|
||||
@ -409,7 +415,7 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
||||
AbstractKart *kart = world->getKart(iei.getKartId());
|
||||
ItemState *is = new ItemState(iei.getNewItemType(), kart,
|
||||
iei.getIndex() );
|
||||
is->initItem(iei.getNewItemType(), iei.getXYZ());
|
||||
is->initItem(iei.getNewItemType(), iei.getXYZ(), iei.getNormal());
|
||||
if (m_switch_ticks >= 0)
|
||||
{
|
||||
ItemState::ItemType new_type = m_switch_to[is->getType()];
|
||||
@ -491,8 +497,9 @@ void NetworkItemManager::restoreState(BareNetworkString *buffer, int count)
|
||||
// A new item was dropped according to the server that is not
|
||||
// yet part of the current state --> create new item
|
||||
Vec3 xyz = is->getXYZ();
|
||||
Vec3 normal = is->getNormal();
|
||||
Item *item_new = dropNewItem(is->getType(), is->getPreviousOwner(),
|
||||
&xyz);
|
||||
&xyz, &normal );
|
||||
if (i != item_new->getItemId())
|
||||
{
|
||||
// The newly created item on the client has been given a
|
||||
|
@ -80,8 +80,10 @@ public:
|
||||
int ticks) OVERRIDE;
|
||||
virtual void collectedItem(ItemState *item, AbstractKart *kart) OVERRIDE;
|
||||
virtual void switchItems() OVERRIDE;
|
||||
virtual Item* dropNewItem(ItemState::ItemType type, const AbstractKart *kart,
|
||||
const Vec3 *xyz=NULL) OVERRIDE;
|
||||
virtual Item* dropNewItem(ItemState::ItemType type,
|
||||
const AbstractKart *kart,
|
||||
const Vec3 *server_xyz = NULL,
|
||||
const Vec3 *server_normal = NULL) OVERRIDE;
|
||||
virtual BareNetworkString* saveState(std::vector<std::string>* ru)
|
||||
OVERRIDE;
|
||||
virtual void restoreState(BareNetworkString *buffer, int count) OVERRIDE;
|
||||
|
Loading…
Reference in New Issue
Block a user