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); }
static v8::Handle<v8::Value> npObjectNamedSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info) { HTMLPlugInElement* imp = C::toNative(info.Holder()); ScriptInstance scriptInstance = imp->getInstance(); if (!scriptInstance) return v8Undefined(); v8::Local<v8::Object> instance = v8::Local<v8::Object>::New(scriptInstance->instance()); if (instance.IsEmpty()) return v8Undefined(); return npObjectSetNamedProperty(instance, name, value, info); }
v8::Handle<v8::Value> npObjectIndexedGetter(uint32_t index, const v8::AccessorInfo& info) { HTMLPlugInElement* imp = C::toNative(info.Holder()); ScriptInstance scriptInstance = imp->getInstance(); if (!scriptInstance) return v8Undefined(); v8::Local<v8::Object> instance = v8::Local<v8::Object>::New(scriptInstance->instance()); if (instance.IsEmpty()) return v8Undefined(); return npObjectGetIndexedProperty(instance, index, info); }
static void npObjectNamedSetter(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<v8::Value>& info) { HTMLPlugInElement* imp = C::toNative(info.Holder()); ScriptInstance scriptInstance = imp->getInstance(); if (!scriptInstance) return; v8::Local<v8::Object> instance = scriptInstance->newLocal(v8::Isolate::GetCurrent()); if (instance.IsEmpty()) return; npObjectSetNamedProperty(instance, name, value, info); }
void npObjectIndexedGetter(uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) { HTMLPlugInElement* imp = C::toNative(info.Holder()); ScriptInstance scriptInstance = imp->getInstance(); if (!scriptInstance) return; v8::Local<v8::Object> instance = scriptInstance->newLocal(v8::Isolate::GetCurrent()); if (instance.IsEmpty()) return; npObjectGetIndexedProperty(instance, index, info); }
// FIXME: need comments. // Params: holder could be HTMLEmbedElement or NPObject static v8::Handle<v8::Value> npObjectInvokeImpl(const v8::Arguments& args, InvokeFunctionType functionId) { NPObject* npObject; // These three types are subtypes of HTMLPlugInElement. if (V8HTMLAppletElement::HasInstance(args.Holder()) || V8HTMLEmbedElement::HasInstance(args.Holder()) || V8HTMLObjectElement::HasInstance(args.Holder())) { // The holder object is a subtype of HTMLPlugInElement. HTMLPlugInElement* element = V8DOMWrapper::convertDOMWrapperToNode<HTMLPlugInElement>(args.Holder()); ScriptInstance scriptInstance = element->getInstance(); if (scriptInstance) npObject = V8DOMWrapper::convertToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, scriptInstance->instance()); else npObject = 0; } else { // The holder object is not a subtype of HTMLPlugInElement, it must be an NPObject which has three // internal fields. if (args.Holder()->InternalFieldCount() != V8Custom::kNPObjectInternalFieldCount) return throwError("NPMethod called on non-NPObject", V8Proxy::ReferenceError); npObject = V8DOMWrapper::convertToNativeObject<NPObject>(V8ClassIndex::NPOBJECT, args.Holder()); } // Verify that our wrapper wasn't using a NPObject which has already been deleted. if (!npObject || !_NPN_IsAlive(npObject)) return throwError("NPObject deleted", V8Proxy::ReferenceError); // Wrap up parameters. int numArgs = args.Length(); OwnArrayPtr<NPVariant> npArgs(new NPVariant[numArgs]); for (int i = 0; i < numArgs; i++) convertV8ObjectToNPVariant(args[i], npObject, &npArgs[i]); NPVariant result; VOID_TO_NPVARIANT(result); switch (functionId) { case InvokeMethod: if (npObject->_class->invoke) { v8::Handle<v8::String> functionName(v8::String::Cast(*args.Data())); NPIdentifier identifier = getStringIdentifier(functionName); npObject->_class->invoke(npObject, identifier, npArgs.get(), numArgs, &result); } break; case InvokeConstruct: if (npObject->_class->construct) npObject->_class->construct(npObject, npArgs.get(), numArgs, &result); break; case InvokeDefault: if (npObject->_class->invokeDefault) npObject->_class->invokeDefault(npObject, npArgs.get(), numArgs, &result); break; default: break; } for (int i=0; i < numArgs; i++) _NPN_ReleaseVariantValue(&npArgs[i]); // Unwrap return values. v8::Handle<v8::Value> returnValue = convertNPVariantToV8Object(&result, npObject); _NPN_ReleaseVariantValue(&result); return returnValue; }
Node* GetScriptContextNode() { ScriptInstance* instance = GetScriptContextInstance(); return instance ? instance->GetNode() : 0; }
// FIXME: need comments. // Params: holder could be HTMLEmbedElement or NPObject static void npObjectInvokeImpl(const v8::FunctionCallbackInfo<v8::Value>& args, InvokeFunctionType functionId) { NPObject* npObject; WrapperWorldType currentWorldType = worldType(args.GetIsolate()); // These three types are subtypes of HTMLPlugInElement. if (V8HTMLAppletElement::HasInstance(args.Holder(), args.GetIsolate(), currentWorldType) || V8HTMLEmbedElement::HasInstance(args.Holder(), args.GetIsolate(), currentWorldType) || V8HTMLObjectElement::HasInstance(args.Holder(), args.GetIsolate(), currentWorldType)) { // The holder object is a subtype of HTMLPlugInElement. HTMLPlugInElement* element; if (V8HTMLAppletElement::HasInstance(args.Holder(), args.GetIsolate(), currentWorldType)) element = V8HTMLAppletElement::toNative(args.Holder()); else if (V8HTMLEmbedElement::HasInstance(args.Holder(), args.GetIsolate(), currentWorldType)) element = V8HTMLEmbedElement::toNative(args.Holder()); else element = V8HTMLObjectElement::toNative(args.Holder()); ScriptInstance scriptInstance = element->getInstance(); if (scriptInstance) { v8::Isolate* isolate = v8::Isolate::GetCurrent(); v8::HandleScope handleScope(isolate); npObject = v8ObjectToNPObject(scriptInstance->newLocal(isolate)); } else npObject = 0; } else { // The holder object is not a subtype of HTMLPlugInElement, it must be an NPObject which has three // internal fields. if (args.Holder()->InternalFieldCount() != npObjectInternalFieldCount) { throwError(v8ReferenceError, "NPMethod called on non-NPObject", args.GetIsolate()); return; } npObject = v8ObjectToNPObject(args.Holder()); } // Verify that our wrapper wasn't using a NPObject which has already been deleted. if (!npObject || !_NPN_IsAlive(npObject)) { throwError(v8ReferenceError, "NPObject deleted", args.GetIsolate()); return; } // Wrap up parameters. int numArgs = args.Length(); OwnArrayPtr<NPVariant> npArgs = adoptArrayPtr(new NPVariant[numArgs]); for (int i = 0; i < numArgs; i++) convertV8ObjectToNPVariant(args[i], npObject, &npArgs[i]); NPVariant result; VOID_TO_NPVARIANT(result); bool retval = true; switch (functionId) { case InvokeMethod: if (npObject->_class->invoke) { v8::Handle<v8::String> functionName = v8::Handle<v8::String>::Cast(args.Data()); NPIdentifier identifier = getStringIdentifier(functionName); retval = npObject->_class->invoke(npObject, identifier, npArgs.get(), numArgs, &result); } break; case InvokeConstruct: if (npObject->_class->construct) retval = npObject->_class->construct(npObject, npArgs.get(), numArgs, &result); break; case InvokeDefault: if (npObject->_class->invokeDefault) retval = npObject->_class->invokeDefault(npObject, npArgs.get(), numArgs, &result); break; default: break; } if (!retval) throwError(v8GeneralError, "Error calling method on NPObject.", args.GetIsolate()); for (int i = 0; i < numArgs; i++) _NPN_ReleaseVariantValue(&npArgs[i]); // Unwrap return values. v8::Handle<v8::Value> returnValue; if (_NPN_IsAlive(npObject)) returnValue = convertNPVariantToV8Object(&result, npObject, args.GetIsolate()); _NPN_ReleaseVariantValue(&result); v8SetReturnValue(args, returnValue); }