void ScriptInstance::HandlePhysicsPostStep(StringHash eventType, VariantMap& eventData) { if (!active_ || !scriptObject_) return; using namespace PhysicsPostStep; if (!fixedUpdateFps_) { VariantVector parameters; parameters.Push(eventData[P_TIMESTEP]); scriptFile_->Execute(scriptObject_, methods_[METHOD_FIXEDPOSTUPDATE], parameters); } else { float timeStep = eventData[P_TIMESTEP].GetFloat(); fixedPostUpdateAcc_ += timeStep; if (fixedPostUpdateAcc_ >= fixedUpdateInterval_) { fixedPostUpdateAcc_ = fmodf(fixedPostUpdateAcc_, fixedUpdateInterval_); VariantVector parameters; parameters.Push(fixedUpdateInterval_); scriptFile_->Execute(scriptObject_, methods_[METHOD_FIXEDPOSTUPDATE], parameters); } } }
VariantVector CrowdManager::GetQueryFilterTypesAttr() const { VariantVector ret; if (crowd_) { unsigned totalNumAreas = 0; for (unsigned i = 0; i < numQueryFilterTypes_; ++i) totalNumAreas += numAreas_[i]; ret.Reserve(numQueryFilterTypes_ * 3 + totalNumAreas + 1); ret.Push(numQueryFilterTypes_); for (unsigned i = 0; i < numQueryFilterTypes_; ++i) { const dtQueryFilter* filter = crowd_->getFilter(i); assert(filter); ret.Push(filter->getIncludeFlags()); ret.Push(filter->getExcludeFlags()); ret.Push(numAreas_[i]); for (unsigned j = 0; j < numAreas_[i]; ++j) ret.Push(filter->getAreaCost(j)); } } else ret.Push(0); return ret; }
VariantVector Cursor::GetShapesAttr() const { VariantVector ret; unsigned numShapes = 0; for (unsigned i = 0; i < CS_MAX_SHAPES; ++i) { if (shapeInfos_[i].imageRect_ != IntRect::ZERO) ++numShapes; } ret.Push(numShapes); for (unsigned i = 0; i < CS_MAX_SHAPES; ++i) { if (shapeInfos_[i].imageRect_ != IntRect::ZERO) { ret.Push(String(shapeNames[i])); ret.Push(GetResourceRef(shapeInfos_[i].texture_, Texture2D::GetTypeStatic())); ret.Push(shapeInfos_[i].imageRect_); ret.Push(shapeInfos_[i].hotSpot_); } } return ret; }
VariantVector DecalSet::GetDecalsAttr() const { VariantVector ret; ret.Push(skinned_); ret.Push(decals_.Size()); for (List<Decal>::ConstIterator i = decals_.Begin(); i != decals_.End(); ++i) { ret.Push(i->timer_); ret.Push(i->timeToLive_); ret.Push(i->vertices_.Size()); ret.Push(i->indices_.Size()); VectorBuffer geometry; for (PODVector<DecalVertex>::ConstIterator j = i->vertices_.Begin(); j != i->vertices_.End(); ++j) { geometry.WriteVector3(j->position_); geometry.WriteVector3(j->normal_); geometry.WriteVector2(j->texCoord_); geometry.WriteVector4(j->tangent_); if (skinned_) { for (unsigned k = 0; k < 4; ++k) geometry.WriteFloat(j->blendWeights_[k]); for (unsigned k = 0; k < 4; ++k) geometry.WriteUByte(j->blendIndices_[k]); } } for (PODVector<unsigned short>::ConstIterator j = i->indices_.Begin(); j != i->indices_.End(); ++j) geometry.WriteUShort(*j); ret.Push(geometry.GetBuffer()); } if (skinned_) { ret.Push(bones_.Size()); for (Vector<Bone>::ConstIterator i = bones_.Begin(); i != bones_.End(); ++i) { ret.Push(i->name_); VectorBuffer boneData; boneData.WriteUByte(i->collisionMask_); if (i->collisionMask_ & BONECOLLISION_SPHERE) boneData.WriteFloat(i->radius_); if (i->collisionMask_ & BONECOLLISION_BOX) boneData.WriteBoundingBox(i->boundingBox_); boneData.Write(i->offsetMatrix_.Data(), sizeof(Matrix3x4)); ret.Push(boneData.GetBuffer()); } } return ret; }
VariantVector CrowdManager::GetObstacleAvoidanceTypesAttr() const { VariantVector ret; if (crowd_) { ret.Reserve(numObstacleAvoidanceTypes_ * 10 + 1); ret.Push(numObstacleAvoidanceTypes_); for (unsigned i = 0; i < numObstacleAvoidanceTypes_; ++i) { const dtObstacleAvoidanceParams* params = crowd_->getObstacleAvoidanceParams(i); assert(params); ret.Push(params->velBias); ret.Push(params->weightDesVel); ret.Push(params->weightCurVel); ret.Push(params->weightSide); ret.Push(params->weightToi); ret.Push(params->horizTime); ret.Push(params->gridSize); ret.Push(params->adaptiveDivs); ret.Push(params->adaptiveRings); ret.Push(params->adaptiveDepth); } } else ret.Push(0); return ret; }
VariantVector ParticleEmitter::GetParticleBillboardsAttr() const { VariantVector ret; if (!serializeParticles_) { ret.Push(billboards_.Size()); return ret; } ret.Reserve(billboards_.Size() * 7 + 1); ret.Push(billboards_.Size()); for (PODVector<Billboard>::ConstIterator i = billboards_.Begin(); i != billboards_.End(); ++i) { 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; }
VariantVector ParticleEmitter::GetColorsAttr() const { VariantVector ret; ret.Reserve(colorFrames_.Size() * 2 + 1); ret.Push(colorFrames_.Size()); for (Vector<ColorFrame>::ConstIterator i = colorFrames_.Begin(); i < colorFrames_.End(); ++i) { ret.Push(i->color_); ret.Push(i->time_); } return ret; }
VariantVector ParticleEmitter::GetTextureFramesAttr() const { VariantVector ret; ret.Reserve(textureFrames_.Size() * 2 + 1); ret.Push(textureFrames_.Size()); for (Vector<TextureFrame>::ConstIterator i = textureFrames_.Begin(); i < textureFrames_.End(); ++i) { ret.Push(i->uv_.ToVector4()); ret.Push(i->time_); } return ret; }
VariantVector AnimationController::GetAnimationsAttr() const { VariantVector ret; ret.Reserve(animations_.Size() * 5); for (Vector<AnimationControl>::ConstIterator i = animations_.Begin(); i != animations_.End(); ++i) { ret.Push(i->name_); ret.Push(i->speed_); ret.Push(i->targetWeight_); ret.Push(i->fadeTime_); ret.Push(i->autoFadeTime_); } return ret; }
VariantVector AnimationController::GetNodeAnimationStatesAttr() const { VariantVector ret; ret.Reserve(nodeAnimationStates_.Size() * 3 + 1); ret.Push(nodeAnimationStates_.Size()); for (Vector<SharedPtr<AnimationState> >::ConstIterator i = nodeAnimationStates_.Begin(); i != nodeAnimationStates_.End(); ++i) { AnimationState* state = *i; Animation* animation = state->GetAnimation(); ret.Push(GetResourceRef(animation, Animation::GetTypeStatic())); ret.Push(state->IsLooped()); ret.Push(state->GetTime()); } return ret; }
void ScriptEventInvoker::HandleScriptEvent(StringHash eventType, VariantMap& eventData) { if (!file_->IsCompiled()) return; asIScriptFunction* method = static_cast<asIScriptFunction*>(GetEventHandler()->GetUserData()); if (object_ && !IsObjectAlive()) { file_->CleanupEventInvoker(object_); return; } VariantVector parameters; if (method->GetParamCount() > 0) { parameters.Push(Variant((void*)&eventType)); parameters.Push(Variant((void*)&eventData)); } if (object_) file_->Execute(object_, method, parameters); else file_->Execute(method, parameters); }
VariantVector AnimatedModel::GetBonesEnabledAttr() const { VariantVector ret; const Vector<Bone>& bones = skeleton_.GetBones(); ret.Reserve(bones.Size()); for (Vector<Bone>::ConstIterator i = bones.Begin(); i != bones.End(); ++i) ret.Push(i->animated_); return ret; }
void ScriptInstance::SetScriptDataAttr(PODVector<unsigned char> data) { if (scriptObject_ && methods_[METHOD_LOAD]) { MemoryBuffer buf(data); VariantVector parameters; parameters.Push(Variant((void*)static_cast<Deserializer*>(&buf))); scriptFile_->Execute(scriptObject_, methods_[METHOD_LOAD], parameters); } }
void ScriptInstance::SetScriptNetworkDataAttr(const PODVector<unsigned char>& data) { if (scriptObject_ && methods_[METHOD_READNETWORKUPDATE]) { MemoryBuffer buf(data); VariantVector parameters; parameters.Push(Variant((void*)static_cast<Deserializer*>(&buf))); scriptFile_->Execute(scriptObject_, methods_[METHOD_READNETWORKUPDATE], parameters); } }
void AngelScriptIntegration::CreateScene() { ResourceCache* cache = GetSubsystem<ResourceCache>(); scene_ = new Scene(context_); // Create the Octree component to the scene so that drawable objects can be rendered. Use default volume // (-1000, -1000, -1000) to (1000, 1000, 1000) scene_->CreateComponent<Octree>(); // Create a Zone component into a child scene node. The Zone controls ambient lighting and fog settings. Like the Octree, // it also defines its volume with a bounding box, but can be rotated (so it does not need to be aligned to the world X, Y // and Z axes.) Drawable objects "pick up" the zone they belong to and use it when rendering; several zones can exist Node* zoneNode = scene_->CreateChild("Zone"); Zone* zone = zoneNode->CreateComponent<Zone>(); // Set same volume as the Octree, set a close bluish fog and some ambient light zone->SetBoundingBox(BoundingBox(-1000.0f, 1000.0f)); zone->SetAmbientColor(Color(0.05f, 0.1f, 0.15f)); zone->SetFogColor(Color(0.1f, 0.2f, 0.3f)); zone->SetFogStart(10.0f); zone->SetFogEnd(100.0f); // Create randomly positioned and oriented box StaticModels in the scene const unsigned NUM_OBJECTS = 2000; for (unsigned i = 0; i < NUM_OBJECTS; ++i) { Node* boxNode = scene_->CreateChild("Box"); boxNode->SetPosition(Vector3(Random(200.0f) - 100.0f, Random(200.0f) - 100.0f, Random(200.0f) - 100.0f)); // Orient using random pitch, yaw and roll Euler angles boxNode->SetRotation(Quaternion(Random(360.0f), Random(360.0f), Random(360.0f))); StaticModel* boxObject = boxNode->CreateComponent<StaticModel>(); boxObject->SetModel(cache->GetResource<Model>("Models/Box.mdl")); boxObject->SetMaterial(cache->GetResource<Material>("Materials/Stone.xml")); // Add our custom Rotator script object (using the ScriptInstance C++ component to instantiate / store it) which will // rotate the scene node each frame, when the scene sends its update event ScriptInstance* instance = boxNode->CreateComponent<ScriptInstance>(); instance->CreateObject(cache->GetResource<ScriptFile>("Scripts/Rotator.as"), "Rotator"); // Call the script object's "SetRotationSpeed" function. Function arguments need to be passed in a VariantVector VariantVector parameters; parameters.Push(Vector3(10.0f, 20.0f, 30.0f)); instance->Execute("void SetRotationSpeed(const Vector3&in)", parameters); } // Create the camera. Let the starting position be at the world origin. As the fog limits maximum visible distance, we can // bring the far clip plane closer for more effective culling of distant objects cameraNode_ = scene_->CreateChild("Camera"); Camera* camera = cameraNode_->CreateComponent<Camera>(); camera->SetFarClip(100.0f); // Create a point light to the camera scene node Light* light = cameraNode_->CreateComponent<Light>(); light->SetLightType(LIGHT_POINT); light->SetRange(30.0f); }
void ScriptInstance::HandlePhysicsPostStep(StringHash eventType, VariantMap& eventData) { if (!scriptObject_) return; using namespace PhysicsPostStep; VariantVector parameters; parameters.Push(eventData[P_TIMESTEP]); scriptFile_->Execute(scriptObject_, methods_[METHOD_FIXEDPOSTUPDATE], parameters); }
void ScriptInstance::HandleScenePostUpdate(StringHash eventType, VariantMap& eventData) { if (!active_ || !scriptObject_) return; using namespace ScenePostUpdate; VariantVector parameters; parameters.Push(eventData[P_TIMESTEP]); scriptFile_->Execute(scriptObject_, methods_[METHOD_POSTUPDATE], parameters); }
VariantVector Cursor::GetShapesAttr() const { VariantVector ret; for (HashMap<String, CursorShapeInfo>::ConstIterator i = shapeInfos_.Begin(); i != shapeInfos_.End(); ++i) { if (i->second_.imageRect_ != IntRect::ZERO) { // Could use a map but this simplifies the UI xml. VariantVector shape; shape.Push(i->first_); shape.Push(GetResourceRef(i->second_.texture_, Texture2D::GetTypeStatic())); shape.Push(i->second_.imageRect_); shape.Push(i->second_.hotSpot_); ret.Push(shape); } } return ret; }
VariantVector ParticleEmitter::GetParticlesAttr() const { VariantVector ret; ret.Reserve(particles_.Size() * 8 + 1); ret.Push(particles_.Size()); for (PODVector<Particle>::ConstIterator i = particles_.Begin(); i != particles_.End(); ++i) { ret.Push(i->velocity_); ret.Push(i->size_); ret.Push(i->timer_); ret.Push(i->timeToLive_); ret.Push(i->scale_); ret.Push(i->rotationSpeed_); ret.Push(i->colorIndex_); ret.Push(i->texIndex_); } return ret; }
PODVector<unsigned char> ScriptInstance::GetScriptDataAttr() const { if (!scriptObject_ || !methods_[METHOD_SAVE]) return PODVector<unsigned char>(); else { VectorBuffer buf; VariantVector parameters; parameters.Push(Variant((void*)static_cast<Serializer*>(&buf))); scriptFile_->Execute(scriptObject_, methods_[METHOD_SAVE], parameters); return buf.GetBuffer(); } }
VariantVector XMLElement::GetVariantVector() const { VariantVector ret; XMLElement variantElem = GetChild("variant"); while (variantElem) { ret.Push(variantElem.GetVariant()); variantElem = variantElem.GetNext("variant"); } return ret; }
void JSONValue::GetVariantVector(VariantVector& variantVector) const { if (!IsArray()) { LOGERROR("JSONValue is not a array"); return; } for (unsigned i = 0; i < Size(); ++i) { Variant variant; (*this)[i].GetVariant(variant); variantVector.Push(variant); } }
void ScriptFile::HandleScriptEvent(StringHash eventType, VariantMap& eventData) { if (!compiled_) return; asIScriptFunction* function = static_cast<asIScriptFunction*>(GetEventHandler()->GetUserData()); VariantVector parameters; if (function->GetParamCount() > 0) { parameters.Push(Variant((void*)&eventType)); parameters.Push(Variant((void*)&eventData)); } Execute(function, parameters); }
void ScriptInstance::HandleScriptEvent(StringHash eventType, VariantMap& eventData) { if (!active_ || !scriptFile_ || !scriptObject_) return; asIScriptFunction* method = static_cast<asIScriptFunction*>(GetEventHandler()->GetUserData()); VariantVector parameters; if (method->GetParamCount() > 0) { parameters.Push(Variant((void*)&eventType)); parameters.Push(Variant((void*)&eventData)); } scriptFile_->Execute(scriptObject_, method, parameters); }
void ScriptInstance::HandleSceneUpdate(StringHash eventType, VariantMap& eventData) { if (!active_ || !scriptObject_) return; using namespace SceneUpdate; float timeStep = eventData[P_TIMESTEP].GetFloat(); // Execute delayed method calls for (unsigned i = 0; i < delayedMethodCalls_.Size();) { DelayedMethodCall& call = delayedMethodCalls_[i]; bool remove = false; call.delay_ -= timeStep; if (call.delay_ <= 0.0f) { if (!call.repeat_) remove = true; else call.delay_ += call.period_; Execute(call.declaration_, call.parameters_); } if (remove) delayedMethodCalls_.Erase(i); else ++i; } // Execute delayed start before first update if (methods_[METHOD_DELAYEDSTART]) { scriptFile_->Execute(scriptObject_, methods_[METHOD_DELAYEDSTART]); methods_[METHOD_DELAYEDSTART] = 0; // Only execute once } if (methods_[METHOD_UPDATE]) { VariantVector parameters; parameters.Push(timeStep); scriptFile_->Execute(scriptObject_, methods_[METHOD_UPDATE], parameters); } }
VariantVector BillboardSet::GetBillboardsAttr() const { VariantVector ret; ret.Reserve(billboards_.Size() * 6 + 1); ret.Push(billboards_.Size()); for (PODVector<Billboard>::ConstIterator i = billboards_.Begin(); i != billboards_.End(); ++i) { 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->enabled_); } return ret; }
VariantVector AnimatedModel::GetAnimationStatesAttr() const { VariantVector ret; ret.Reserve(animationStates_.Size() * 6 + 1); ret.Push(animationStates_.Size()); for (Vector<SharedPtr<AnimationState> >::ConstIterator i = animationStates_.Begin(); i != animationStates_.End(); ++i) { AnimationState* state = *i; Animation* animation = state->GetAnimation(); Bone* startBone = state->GetStartBone(); ret.Push(GetResourceRef(animation, Animation::GetTypeStatic())); ret.Push(startBone ? startBone->name_ : String::EMPTY); ret.Push(state->IsLooped()); ret.Push(state->GetWeight()); ret.Push(state->GetTime()); ret.Push((int)state->GetLayer()); } return ret; }
VariantVector RaycastVehicle::GetWheelDataAttr() const { VariantVector ret; ret.Reserve(GetNumWheels() * 22 + 1); ret.Push(GetNumWheels()); for (int i = 0; i < GetNumWheels(); i++) { Node* wNode = GetWheelNode(i); int node_id = wNode->GetID(); URHO3D_LOGDEBUG("RaycastVehicle: Saving node id = " + String(node_id)); ret.Push(node_id); ret.Push(GetWheelDirection(i)); ret.Push(GetWheelAxle(i)); ret.Push(GetWheelRestLength(i)); ret.Push(GetWheelRadius(i)); ret.Push(IsFrontWheel(i)); ret.Push(GetSteeringValue(i)); ret.Push(GetWheelConnectionPoint(i)); ret.Push(origRotation_[i]); ret.Push(GetWheelSkidInfoCumulative(i)); ret.Push(GetWheelSideSlipSpeed(i)); ret.Push(WheelIsGrounded(i)); ret.Push(GetContactPosition(i)); ret.Push(GetContactNormal(i)); // 14 ret.Push(GetWheelSuspensionStiffness(i)); ret.Push(GetWheelDampingRelaxation(i)); ret.Push(GetWheelDampingCompression(i)); ret.Push(GetWheelFrictionSlip(i)); ret.Push(GetWheelRollInfluence(i)); ret.Push(GetEngineForce(i)); ret.Push(GetBrake(i)); ret.Push(GetWheelSkidInfo(i)); } URHO3D_LOGDEBUG("RaycastVehicle: saved items: " + String(ret.Size())); URHO3D_LOGDEBUG("maxSideSlipSpeed_ value save: " + String(maxSideSlipSpeed_)); return ret; }
void SceneResolver::Resolve() { // Nodes do not have component or node ID attributes, so only have to go through components HashSet<StringHash> noIDAttributes; for (HashMap<unsigned, WeakPtr<Component> >::ConstIterator i = components_.Begin(); i != components_.End(); ++i) { Component* component = i->second_; if (!component || noIDAttributes.Contains(component->GetType())) continue; bool hasIDAttributes = false; const Vector<AttributeInfo>* attributes = component->GetAttributes(); if (!attributes) { noIDAttributes.Insert(component->GetType()); continue; } for (unsigned j = 0; j < attributes->Size(); ++j) { const AttributeInfo& info = attributes->At(j); if (info.mode_ & AM_NODEID) { hasIDAttributes = true; unsigned oldNodeID = component->GetAttribute(j).GetUInt(); if (oldNodeID) { HashMap<unsigned, WeakPtr<Node> >::ConstIterator k = nodes_.Find(oldNodeID); if (k != nodes_.End() && k->second_) { unsigned newNodeID = k->second_->GetID(); component->SetAttribute(j, Variant(newNodeID)); } else URHO3D_LOGWARNING("Could not resolve node ID " + String(oldNodeID)); } } else if (info.mode_ & AM_COMPONENTID) { hasIDAttributes = true; unsigned oldComponentID = component->GetAttribute(j).GetUInt(); if (oldComponentID) { HashMap<unsigned, WeakPtr<Component> >::ConstIterator k = components_.Find(oldComponentID); if (k != components_.End() && k->second_) { unsigned newComponentID = k->second_->GetID(); component->SetAttribute(j, Variant(newComponentID)); } else URHO3D_LOGWARNING("Could not resolve component ID " + String(oldComponentID)); } } else if (info.mode_ & AM_NODEIDVECTOR) { hasIDAttributes = true; const VariantVector& oldNodeIDs = component->GetAttribute(j).GetVariantVector(); if (oldNodeIDs.Size()) { // The first index stores the number of IDs redundantly. This is for editing unsigned numIDs = oldNodeIDs[0].GetUInt(); VariantVector newIDs; newIDs.Push(numIDs); for (unsigned k = 1; k < oldNodeIDs.Size(); ++k) { unsigned oldNodeID = oldNodeIDs[k].GetUInt(); HashMap<unsigned, WeakPtr<Node> >::ConstIterator l = nodes_.Find(oldNodeID); if (l != nodes_.End() && l->second_) newIDs.Push(l->second_->GetID()); else { // If node was not found, retain number of elements, just store ID 0 newIDs.Push(0); URHO3D_LOGWARNING("Could not resolve node ID " + String(oldNodeID)); } } component->SetAttribute(j, newIDs); } } } // If component type had no ID attributes, cache this fact for optimization if (!hasIDAttributes) noIDAttributes.Insert(component->GetType()); } // Attributes have been resolved, so no need to remember the nodes after this Reset(); }