int32_t CXFA_ScriptContext::ResolveObjects(CXFA_Object* refNode, const CFX_WideStringC& wsExpression, XFA_RESOLVENODE_RS& resolveNodeRS, uint32_t dwStyles, CXFA_Node* bindNode) { if (wsExpression.IsEmpty()) { return 0; } if (m_eScriptType != XFA_SCRIPTLANGTYPE_Formcalc || (dwStyles & (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings))) { m_upObjectArray.RemoveAll(); } if (refNode && refNode->IsNode() && (dwStyles & (XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings))) { m_upObjectArray.Add(refNode->AsNode()); } FX_BOOL bNextCreate = FALSE; if (dwStyles & XFA_RESOLVENODE_CreateNode) { m_ResolveProcessor->GetNodeHelper()->SetCreateNodeType(bindNode); } m_ResolveProcessor->GetNodeHelper()->m_pCreateParent = nullptr; m_ResolveProcessor->GetNodeHelper()->m_iCurAllStart = -1; CXFA_ResolveNodesData rndFind; int32_t nStart = 0; int32_t nLevel = 0; int32_t nRet = -1; rndFind.m_pSC = this; CXFA_ObjArray findNodes; findNodes.Add(refNode ? refNode : m_pDocument->GetRoot()); int32_t nNodes = 0; while (TRUE) { nNodes = findNodes.GetSize(); int32_t i = 0; rndFind.m_dwStyles = dwStyles; m_ResolveProcessor->SetCurStart(nStart); nStart = m_ResolveProcessor->GetFilter(wsExpression, nStart, rndFind); if (nStart < 1) { if ((dwStyles & XFA_RESOLVENODE_CreateNode) && !bNextCreate) { CXFA_Node* pDataNode = nullptr; nStart = m_ResolveProcessor->GetNodeHelper()->m_iCurAllStart; if (nStart != -1) { pDataNode = m_pDocument->GetNotBindNode(findNodes); if (pDataNode) { findNodes.RemoveAll(); findNodes.Add(pDataNode); break; } } else { pDataNode = findNodes[0]->AsNode(); findNodes.RemoveAll(); findNodes.Add(pDataNode); break; } dwStyles |= XFA_RESOLVENODE_Bind; findNodes.RemoveAll(); findNodes.Add(m_ResolveProcessor->GetNodeHelper()->m_pAllStartParent); continue; } else { break; } } if (bNextCreate) { FX_BOOL bCreate = m_ResolveProcessor->GetNodeHelper()->ResolveNodes_CreateNode( rndFind.m_wsName, rndFind.m_wsCondition, nStart == wsExpression.GetLength(), this); if (bCreate) { continue; } else { break; } } CXFA_ObjArray retNodes; while (i < nNodes) { FX_BOOL bDataBind = FALSE; if (((dwStyles & XFA_RESOLVENODE_Bind) || (dwStyles & XFA_RESOLVENODE_CreateNode)) && nNodes > 1) { CXFA_ResolveNodesData rndBind; m_ResolveProcessor->GetFilter(wsExpression, nStart, rndBind); m_ResolveProcessor->SetIndexDataBind(rndBind.m_wsCondition, i, nNodes); bDataBind = TRUE; } rndFind.m_CurNode = findNodes[i++]; rndFind.m_nLevel = nLevel; rndFind.m_dwFlag = XFA_RESOVENODE_RSTYPE_Nodes; nRet = m_ResolveProcessor->Resolve(rndFind); if (nRet < 1) { continue; } if (rndFind.m_dwFlag == XFA_RESOVENODE_RSTYPE_Attribute && rndFind.m_pScriptAttribute && nStart < wsExpression.GetLength()) { std::unique_ptr<CFXJSE_Value> pValue(new CFXJSE_Value(m_pIsolate)); (rndFind.m_Nodes[0]->*(rndFind.m_pScriptAttribute->lpfnCallback))( pValue.get(), FALSE, (XFA_ATTRIBUTE)rndFind.m_pScriptAttribute->eAttribute); rndFind.m_Nodes.SetAt(0, ToObject(pValue.get(), nullptr)); } int32_t iSize = m_upObjectArray.GetSize(); if (iSize) { m_upObjectArray.RemoveAt(iSize - 1); } retNodes.Append(rndFind.m_Nodes); rndFind.m_Nodes.RemoveAll(); if (bDataBind) { break; } } findNodes.RemoveAll(); nNodes = retNodes.GetSize(); if (nNodes < 1) { if (dwStyles & XFA_RESOLVENODE_CreateNode) { bNextCreate = TRUE; if (!m_ResolveProcessor->GetNodeHelper()->m_pCreateParent) { m_ResolveProcessor->GetNodeHelper()->m_pCreateParent = ToNode(rndFind.m_CurNode); m_ResolveProcessor->GetNodeHelper()->m_iCreateCount = 1; } FX_BOOL bCreate = m_ResolveProcessor->GetNodeHelper()->ResolveNodes_CreateNode( rndFind.m_wsName, rndFind.m_wsCondition, nStart == wsExpression.GetLength(), this); if (bCreate) { continue; } else { break; } } else { break; } } findNodes.Copy(retNodes); rndFind.m_Nodes.RemoveAll(); if (nLevel == 0) { dwStyles &= ~(XFA_RESOLVENODE_Parent | XFA_RESOLVENODE_Siblings); } nLevel++; } if (!bNextCreate) { resolveNodeRS.dwFlags = rndFind.m_dwFlag; if (nNodes > 0) { resolveNodeRS.nodes.Append(findNodes); } if (rndFind.m_dwFlag == XFA_RESOVENODE_RSTYPE_Attribute) { resolveNodeRS.pScriptAttribute = rndFind.m_pScriptAttribute; return 1; } } if (dwStyles & (XFA_RESOLVENODE_CreateNode | XFA_RESOLVENODE_Bind | XFA_RESOLVENODE_BindNew)) { m_ResolveProcessor->SetResultCreateNode(resolveNodeRS, rndFind.m_wsCondition); if (!bNextCreate && (dwStyles & XFA_RESOLVENODE_CreateNode)) { resolveNodeRS.dwFlags = XFA_RESOVENODE_RSTYPE_ExistNodes; } return resolveNodeRS.nodes.GetSize(); } return nNodes; }
JSValue::operator JSObjectRef() const { return ToObject(); }
//============================== // VRMenuMgrLocal::SubmitForRenderingRecursive void VRMenuMgrLocal::SubmitForRenderingRecursive( OvrDebugLines & debugLines, BitmapFont const & font, BitmapFontSurface & fontSurface, VRMenuRenderFlags_t const & flags, VRMenuObjectLocal const * obj, Posef const & parentModelPose, Vector4f const & parentColor, Vector3f const & parentScale, Bounds3f & cullBounds, SubmittedMenuObject * submitted, int const maxIndices, int & curIndex ) const { if ( curIndex >= maxIndices ) { // If this happens we're probably not correctly clearing the submitted surfaces each frame // OR we've got a LOT of surfaces. LOG( "maxIndices = %i, curIndex = %i", maxIndices, curIndex ); DROID_ASSERT( curIndex < maxIndices, "VrMenu" ); return; } // check if this object is hidden if ( obj->GetFlags() & VRMENUOBJECT_DONT_RENDER ) { return; } Posef const & localPose = obj->GetLocalPose(); Posef curModelPose; curModelPose.Position = parentModelPose.Position + ( parentModelPose.Orientation * parentScale.EntrywiseMultiply( localPose.Position ) ); curModelPose.Orientation = localPose.Orientation * parentModelPose.Orientation; Vector4f curColor = parentColor * obj->GetColor(); Vector3f const & localScale = obj->GetLocalScale(); Vector3f scale = parentScale.EntrywiseMultiply( localScale ); OVR_ASSERT( obj != NULL ); /* VRMenuObject const * parent = ToObject( obj->GetParentHandle() ); if ( parent != NULL ) { fontParms_t fontParms; Vector3f itemUp = curModelPose.Orientation * Vector3f( 0.0f, 1.0f, 0.0f ); Vector3f itemNormal = curModelPose.Orientation * Vector3f( 0.0f, 0.0f, 1.0f ); fontSurface.DrawText3D( font, fontParms, curModelPose.Position, itemNormal, itemUp, 1.0f, Vector4f( 1.0f, 0.0f, 1.0f, 1.0f ), parent->GetText().ToCStr() ); } */ if ( obj->GetType() != VRMENU_CONTAINER ) // containers never render, but their children may { Posef const & hilightPose = obj->GetHilightPose(); Posef itemPose( curModelPose.Orientation * hilightPose.Orientation, curModelPose.Position + ( curModelPose.Orientation * parentScale.EntrywiseMultiply( hilightPose.Position ) ) ); Matrix4f poseMat( itemPose.Orientation ); Vector3f itemUp = poseMat.GetYBasis(); Vector3f itemNormal = poseMat.GetZBasis(); curModelPose = itemPose; // so children like the slider bar caret use our hilight offset and don't end up clipping behind us! VRMenuRenderFlags_t rFlags = flags; VRMenuObjectFlags_t oFlags = obj->GetFlags(); if ( oFlags & VRMENUOBJECT_FLAG_POLYGON_OFFSET ) { rFlags |= VRMENU_RENDER_POLYGON_OFFSET; } if ( oFlags & VRMENUOBJECT_FLAG_NO_DEPTH ) { rFlags |= VRMENU_RENDER_NO_DEPTH; } // the menu object may have zero or more renderable surfaces (if 0, it may draw only text) Array< VRMenuSurface > const & surfaces = obj->GetSurfaces(); for ( int i = 0; i < surfaces.GetSizeI(); ++i ) { VRMenuSurface const & surf = surfaces[i]; if ( surf.IsRenderable() ) { SubmittedMenuObject & sub = submitted[curIndex]; sub.SurfaceIndex = i; sub.Pose = itemPose; sub.Scale = scale; sub.Flags = rFlags; sub.ColorTableOffset = obj->GetColorTableOffset(); sub.SkipAdditivePass = !obj->IsHilighted(); sub.Handle = obj->GetHandle(); // modulate surface color with parent's current color sub.Color = surf.GetColor() * curColor; sub.Offsets = surf.GetAnchorOffsets(); sub.FadeDirection = obj->GetFadeDirection(); #if defined( OVR_BUILD_DEBUG ) sub.SurfaceName = surf.GetName(); #endif curIndex++; } } OVR::String const & text = obj->GetText(); if ( ( oFlags & VRMENUOBJECT_DONT_RENDER_TEXT ) == 0 && text.GetLengthI() > 0 ) { Posef const & textLocalPose = obj->GetTextLocalPose(); Posef curTextPose; curTextPose.Position = itemPose.Position + ( itemPose.Orientation * textLocalPose.Position * scale ); curTextPose.Orientation = textLocalPose.Orientation * itemPose.Orientation; Vector3f textNormal = curTextPose.Orientation * Vector3f( 0.0f, 0.0f, 1.0f ); Vector3f position = curTextPose.Position + textNormal * 0.001f; // this is simply to prevent z-fighting right now Vector3f textScale = scale * obj->GetTextLocalScale(); Vector4f textColor = obj->GetTextColor(); // Apply parent's alpha influence textColor.w *= parentColor.w; VRMenuFontParms const & fp = obj->GetFontParms(); fontParms_t fontParms; fontParms.CenterHoriz = fp.CenterHoriz; fontParms.CenterVert = fp.CenterVert; fontParms.Billboard = fp.Billboard; fontParms.TrackRoll = fp.TrackRoll; fontParms.ColorCenter = fp.ColorCenter; fontParms.AlphaCenter = fp.AlphaCenter; fontSurface.DrawText3D( font, fontParms, position, itemNormal, itemUp, textScale.x * fp.Scale, textColor, text.ToCStr() ); #if 0 // this shows a ruler for the wrap width when rendering text float const wrapw = obj->GetWrapWidth(); Vector3f pos = position + Vector3f( 0.0f, 0.0f, -0.1f ); debugLines.AddLine( pos - wrapw * 0.5f * scale, pos + wrapw * 0.5f * scale, Vector4f( 0.0f, 1.0f, 0.0f, 1.0f ), Vector4f( 1.0f, 0.0f, 0.0f, 1.0f ), 0, false ); #endif } //DROIDLOG( "Spam", "AddPoint for '%s'", text.ToCStr() ); //GetDebugLines().AddPoint( curModelPose.Position, 0.05f, 1, true ); } cullBounds = obj->GetLocalBounds( font ) * parentScale; // submit all children if ( obj->Children.GetSizeI() > 0 ) { for ( int i = 0; i < obj->Children.GetSizeI(); ++i ) { menuHandle_t childHandle = obj->Children[i]; VRMenuObjectLocal const * child = static_cast< VRMenuObjectLocal const * >( ToObject( childHandle ) ); if ( child == NULL ) { continue; } Bounds3f childCullBounds; SubmitForRenderingRecursive( debugLines, font, fontSurface, flags, child, curModelPose, curColor, scale, childCullBounds, submitted, maxIndices, curIndex ); Posef pose = child->GetLocalPose(); pose.Position = pose.Position * scale; childCullBounds = Bounds3f::Transform( pose, childCullBounds ); cullBounds = Bounds3f::Union( cullBounds, childCullBounds ); } } obj->SetCullBounds( cullBounds ); #if 0 OvrCollisionPrimitive const * cp = obj->GetCollisionPrimitive(); if ( cp != NULL ) { cp->DebugRender( debugLines, curModelPose ); } { // for debug drawing, put the cull bounds in world space //LogBounds( obj->GetText().ToCStr(), "Transformed CullBounds", myCullBounds ); debugLines.AddBounds( curModelPose, obj->GetCullBounds(), Vector4f( 0.0f, 1.0f, 1.0f, 1.0f ) ); } { Bounds3f localBounds = obj->GetLocalBounds( font ) * parentScale; //LogBounds( obj->GetText().ToCStr(), "localBounds", localBounds ); debugLines.AddBounds( curModelPose, localBounds, Vector4f( 1.0f, 0.0f, 0.0f, 1.0f ) ); Bounds3f textLocalBounds = obj->GetTextLocalBounds( font ); Posef hilightPose = obj->GetHilightPose(); textLocalBounds = Bounds3f::Transform( Posef( hilightPose.Orientation, hilightPose.Position * scale ), textLocalBounds ); debugLines.AddBounds( curModelPose, textLocalBounds * parentScale, Vector4f( 1.0f, 1.0f, 0.0f, 1.0f ) ); } #endif }
//============================== // VRMenuMgrLocal::RenderSubmitted void VRMenuMgrLocal::RenderSubmitted( Matrix4f const & worldMVP ) const { if ( NumSubmitted == 0 ) { return; } GL_CheckErrors( "VRMenuMgrLocal::RenderSubmitted - pre" ); //LOG( "VRMenuMgrLocal::RenderSubmitted" ); //LOG( "VRMenuMgrLocal::RenderSubmitted - rendering %i objects", NumSubmitted ); bool depthEnabled = true; glEnable( GL_DEPTH_TEST ); bool polygonOffset = false; glDisable( GL_POLYGON_OFFSET_FILL ); glPolygonOffset( 0.0f, -10.0f ); for ( int i = 0; i < NumSubmitted; ++i ) { int idx = SortKeys[i].Key & 0xFFFFFFFF; #if 0 int di = SortKeys[i].Key >> 32ULL; float const df = *((float*)(&di )); LOG( "Surface '%s', sk = %llu, df = %.2f, idx = %i", Submitted[idx].SurfaceName.ToCStr(), SortKeys[i].Key, df, idx ); #endif SubmittedMenuObject const & cur = Submitted[idx]; VRMenuObjectLocal const * obj = static_cast< VRMenuObjectLocal const * >( ToObject( cur.Handle ) ); if ( obj != NULL ) { // TODO: this could be made into a generic template for any glEnable() flag if ( cur.Flags & VRMENU_RENDER_NO_DEPTH ) { if ( depthEnabled ) { glDisable( GL_DEPTH_TEST ); depthEnabled = false; } } else if ( !( cur.Flags & VRMENU_RENDER_NO_DEPTH ) ) { if ( !depthEnabled ) { glEnable( GL_DEPTH_TEST ); depthEnabled = true; } } if ( cur.Flags & VRMENU_RENDER_POLYGON_OFFSET ) { if ( !polygonOffset ) { glEnable( GL_POLYGON_OFFSET_FILL ); polygonOffset = true; } } else { if ( polygonOffset ) { glDisable( GL_POLYGON_OFFSET_FILL ); polygonOffset = false; } } Vector3f translation( cur.Pose.Position.x + cur.Offsets.x, cur.Pose.Position.y + cur.Offsets.y, cur.Pose.Position.z ); Matrix4f transform( cur.Pose.Orientation ); Matrix4f scaleMatrix; scaleMatrix.M[0][0] = cur.Scale.x; scaleMatrix.M[1][1] = cur.Scale.y; scaleMatrix.M[2][2] = cur.Scale.z; transform *= scaleMatrix; transform.SetTranslation( translation ); Matrix4f mvp = transform.Transposed() * worldMVP; obj->RenderSurface( *this, mvp, cur ); } } glDisable( GL_POLYGON_OFFSET_FILL ); GL_CheckErrors( "VRMenuMgrLocal::RenderSubmitted - post" ); }
void CallJavascriptFunction(Handle<Context> context, Handle<Value> This, UFunction* SignatureFunction, Handle<Function> func, void* Parms) { SCOPE_CYCLE_COUNTER(STAT_JavascriptFunctionCallToJavascript); auto isolate = context->GetIsolate(); HandleScope handle_scope(isolate); auto Buffer = reinterpret_cast<uint8*>(Parms); enum { MaxArgs = 32 }; Handle<Value> argv[MaxArgs]; int argc = 0; TFieldIterator<UProperty> Iter(SignatureFunction); for (; Iter && argc < MaxArgs && (Iter->PropertyFlags & (CPF_Parm | CPF_ReturnParm)) == CPF_Parm; ++Iter) { UProperty* Param = *Iter; argv[argc++] = ReadProperty(isolate, Param, Buffer, FNoPropertyOwner()); } UProperty* ReturnParam = nullptr; for (; Iter; ++Iter) { UProperty* Param = *Iter; if (Param->GetPropertyFlags() & CPF_ReturnParm) { ReturnParam = Param; break; } } TryCatch try_catch; auto value = func->Call(This, argc, argv); if (try_catch.HasCaught()) { FJavascriptContext::FromV8(context)->UncaughtException(FV8Exception::Report(try_catch)); } bool bHasAnyOutParams = false; if (SignatureFunction && SignatureFunction->HasAnyFunctionFlags(FUNC_HasOutParms)) { // Iterate over input parameters for (TFieldIterator<UProperty> It(SignatureFunction); It && (It->PropertyFlags & (CPF_Parm | CPF_ReturnParm)) == CPF_Parm; ++It) { // This is 'out ref'! if ((It->PropertyFlags & (CPF_ConstParm | CPF_OutParm)) == CPF_OutParm) { bHasAnyOutParams = true; break; } } } if (bHasAnyOutParams) { FIsolateHelper I(isolate); if (value.IsEmpty() || !value->IsObject()) { I.Throw(TEXT("...")); return; } auto Object = value->ToObject(); // Iterate over parameters again for (TFieldIterator<UProperty> It(SignatureFunction); It; ++It) { UProperty* Param = *It; auto PropertyFlags = Param->GetPropertyFlags(); // pass return parameter as '$' if (PropertyFlags & CPF_ReturnParm) { auto sub_value = Object->Get(I.Keyword("$")); WriteProperty(isolate, ReturnParam, Buffer, sub_value); } // rejects 'const T&' and pass 'T&' as its name else if ((PropertyFlags & (CPF_ConstParm | CPF_OutParm)) == CPF_OutParm) { auto sub_value = Object->Get(I.Keyword(Param->GetName())); if (!sub_value.IsEmpty()) { // value can be null if isolate is in trouble WriteProperty(isolate, Param, Buffer, sub_value); } } } } else { if (ReturnParam) { WriteProperty(isolate, ReturnParam, Buffer, value); } } }