/** * ParamList = "(" [ ( Param [{ "," Param }] [ "," "..." ] ) | "..." | "void" ] ")" */ void parserParamList (parserCtx* ctx, ast* Node, bool inDecl) { debugEnter("ParamList"); tokenMatchPunct(ctx, punctLParen); if (!tokenIsPunct(ctx, punctRParen)) { tokenLocation voidloc = ctx->location; bool end = false; /*Either an empty prototype declaration, or the beginning of a void* parameter*/ if (tokenTryMatchKeyword(ctx, keywordVoid)) { if (!tokenIsPunct(ctx, punctRParen)) { ast* basic = astCreateLiteralIdent(voidloc, strdup("void")); ast* expr = parserDeclExpr(ctx, inDecl, symParam); ast* param = astCreateParam(voidloc, basic, expr); param->symbol = basic->symbol = symFind(ctx->scope, "void"); astAddChild(Node, param); if (!tokenTryMatchPunct(ctx, punctComma)) end = true; } else end = true; } if (!end) do { if (tokenIsPunct(ctx, punctEllipsis)) { astAddChild(Node, astCreate(astEllipsis, ctx->location)); tokenMatch(ctx); break; } else astAddChild(Node, parserParam(ctx, inDecl)); } while (tokenTryMatchPunct(ctx, punctComma)); } tokenMatchPunct(ctx, punctRParen); debugLeave(); }
int main() { ASTREE* root,*ast1,*ast2,*ast3,*ast4,*ast5,*ast6; //DICT_NODE *symbol = malloc(sizeof(DICT_NODE*)); ast1=astCreate(5,0,0, 0, 0, 0); ast2=astCreate(6,0,0, 0, 0, 0); ast3=astCreate(7,0,0, 0, 0, 0); ast4=astCreate(7,0,0, 0, 0, 0); ast5=astCreate(7,0,0, 0, 0, 0); ast6=astCreate(7,0,0, 0, 0, 0); ast4=astCreate(7,0,0, ast5, ast6, 0); root=astCreate(5,0,ast1, ast2, ast3, ast4); //------------------------------------------------ gv_init("testando.dot"); astReadTree(root); gv_close(); return 0; }
ast* astCreateTOP (tokenLocation location, ast* cond, ast* l, ast* r) { ast* Node = astCreate(astTOP, location); astAddChild(Node, cond); Node->l = l; Node->r = r; return Node; }
ast* astCreateBOP (tokenLocation location, ast* l, opTag o, ast* r) { ast* Node = astCreate(astBOP, location); Node->l = l; Node->o = o; Node->r = r; return Node; }
ast* astCreateUsing (tokenLocation location, char* name) { ast* Node = astCreate(astUsing, location); Node->litTag = literalStr; Node->literal = (void*) name; return Node; }
ast* astCreateEmpty (tokenLocation location) { return astCreate(astEmpty, location); }
ast* astCreateMarker (tokenLocation location, markerTag marker) { ast* Node = astCreate(astMarker, location); Node->marker = marker; return Node; }
ast* astCreateConst (tokenLocation location, ast* r) { ast* Node = astCreate(astConst, location); Node->r = r; return Node; }
ast* astCreateEnum (tokenLocation location, ast* name) { ast* Node = astCreate(astEnum, location); Node->l = name; return Node; }
ast* astCreateStruct (tokenLocation location, ast* name) { ast* Node = astCreate(astStruct, location); Node->l = name; return Node; }
ast* astCreateDecl (tokenLocation location, ast* basic) { ast* Node = astCreate(astDecl, location); Node->l = basic; return Node; }
ast* astCreateCast (tokenLocation location, ast* result, ast* r) { ast* Node = astCreate(astCast, location); Node->l = result; Node->r = r; return Node; }
ast* astCreateCall (tokenLocation location, ast* function) { ast* Node = astCreate(astCall, location); Node->l = function; return Node; }
ast* astCreateIndex (tokenLocation location, ast* base, ast* index) { ast* Node = astCreate(astIndex, location); Node->l = base; Node->r = index; return Node; }
ast* astCreateUOP (tokenLocation location, opTag o, ast* r) { ast* Node = astCreate(astUOP, location); Node->o = o; Node->r = r; return Node; }
ast* astCreateFnImpl (tokenLocation location, ast* decl) { ast* Node = astCreate(astFnImpl, location); Node->l = decl; return Node; }
ast* astCreateSizeof (tokenLocation location, ast* r) { ast* Node = astCreate(astSizeof, location); Node->r = r; return Node; }
ast* astCreateType (tokenLocation location, ast* basic, ast* expr) { ast* Node = astCreate(astType, location); Node->l = basic; Node->r = expr; return Node; }
ast* astCreateLiteral (tokenLocation location, literalTag litTag) { ast* Node = astCreate(astLiteral, location); Node->litTag = litTag; return Node; }
ast* astCreateParam (tokenLocation location, ast* basic, ast* expr) { ast* Node = astCreate(astParam, location); Node->l = basic; Node->r = expr; return Node; }
GameObjInst* astCreate(GameObjInst* pSrc) { GameObjInst* pInst; AEVec2 pos, vel; f32 t, angle, size; if (pSrc) { f32 posOffset = pSrc->scale * 0.25f; f32 velOffset = (AST_SIZE_MAX - pSrc->scale + 1.0f) * 0.25f; f32 scaleNew = pSrc->scale * 0.5f; sparkCreate(PTCL_EXPLOSION_L, &pSrc->posCurr, 5, 0.0f * PI - 0.01f * PI, 0.0f * PI + 0.01f * PI, 0.0f, pSrc->scale / AST_SIZE_MAX, &pSrc->velCurr); sparkCreate(PTCL_EXPLOSION_L, &pSrc->posCurr, 5, 0.5f * PI - 0.01f * PI, 0.5f * PI + 0.01f * PI, 0.0f, pSrc->scale / AST_SIZE_MAX, &pSrc->velCurr); sparkCreate(PTCL_EXPLOSION_L, &pSrc->posCurr, 5, 1.0f * PI - 0.01f * PI, 1.0f * PI + 0.01f * PI, 0.0f, pSrc->scale / AST_SIZE_MAX, &pSrc->velCurr); sparkCreate(PTCL_EXPLOSION_L, &pSrc->posCurr, 5, 1.5f * PI - 0.01f * PI, 1.5f * PI + 0.01f * PI, 0.0f, pSrc->scale / AST_SIZE_MAX, &pSrc->velCurr); pInst = astCreate(0); pInst->scale = scaleNew; AEVec2Set(&pInst->posCurr, pSrc->posCurr.x - posOffset, pSrc->posCurr.y - posOffset); AEVec2Set(&pInst->velCurr, pSrc->velCurr.x - velOffset, pSrc->velCurr.y - velOffset); pInst = astCreate(0); pInst->scale = scaleNew; AEVec2Set(&pInst->posCurr, pSrc->posCurr.x + posOffset, pSrc->posCurr.y - posOffset); AEVec2Set(&pInst->velCurr, pSrc->velCurr.x + velOffset, pSrc->velCurr.y - velOffset); pInst = astCreate(0); pInst->scale = scaleNew; AEVec2Set(&pInst->posCurr, pSrc->posCurr.x - posOffset, pSrc->posCurr.y + posOffset); AEVec2Set(&pInst->velCurr, pSrc->velCurr.x - velOffset, pSrc->velCurr.y + velOffset); pSrc->scale = scaleNew; AEVec2Set(&pSrc->posCurr, pSrc->posCurr.x + posOffset, pSrc->posCurr.y + posOffset); AEVec2Set(&pSrc->velCurr, pSrc->velCurr.x + velOffset, pSrc->velCurr.y + velOffset); return pSrc; } // pick a random angle and velocity magnitude angle = AERandFloat() * 2.0f * PI; size = AERandFloat() * (AST_SIZE_MAX - AST_SIZE_MIN) + AST_SIZE_MIN; // pick a random position along the top or left edge if ((t = AERandFloat()) < 0.5f) AEVec2Set(&pos, gAEWinMinX + (t * 2.0f) * (gAEWinMaxX - gAEWinMinX), gAEWinMinY - size * 0.5f); else AEVec2Set(&pos, gAEWinMinX - size * 0.5f, gAEWinMinY + ((t - 0.5f) * 2.0f) * (gAEWinMaxY - gAEWinMinY)); // calculate the velocity vector AEVec2Set (&vel, AECos(angle), AESin(angle)); AEVec2Scale (&vel, &vel, AERandFloat() * (AST_VEL_MAX - AST_VEL_MIN) + AST_VEL_MIN); // create the object instance pInst = gameObjInstCreate(TYPE_ASTEROID, size, &pos, &vel, 0.0f, true); AE_ASSERT(pInst); // set the life based on the size pInst->life = size / AST_SIZE_MAX * AST_LIFE_MAX; return pInst; }
ast* astCreateUnion (tokenLocation location, ast* name) { ast* Node = astCreate(astUnion, location); Node->l = name; return Node; }
ast* astCreateInvalid (tokenLocation location) { return astCreate(astInvalid, location); }
ast* astCreateAssert (tokenLocation location, ast* expr) { ast* Node = astCreate(astAssert, location); Node->r = expr; return Node; }
void GameStatePlayUpdate(void) { if (AEInputCheckTriggered(DIK_J)) SendJoinMessage(); MsgInput inputMsg; if(ProcInput(inputMsg)) { strcpy(inputMsg.data_.username_.name_, client.config_.username_.c_str()); NetworkMessage netMsg; netMsg << inputMsg; netMsg.receiverAddress_ = client.remoteAddr_; try { printf("\nSending INPUT message... Input Count = %d\n", inputMsg.data_.key_info_count_); client.udpSock_.Send(netMsg); } catch(iSocket::SockErr& e) { e.Print(); } } char buffer[1000] = { 0 }; sprintf(buffer, "TIME LEFT: %.2f", time); AEGfxPrint(300, 10, 0xFFFFFFFF, buffer); sprintf(buffer, "Round: %u", round); AEGfxPrint(350, 30, 0xFFFFFFFF, buffer); unsigned yPos = 10; unsigned xPos = 10; for(std::vector<ResultStatus>::iterator it = results.begin(); it != results.end(); ++it) { sprintf(buffer, "%s: Score: %u", it->name_.name_, it->score_); AEGfxPrint(xPos, yPos, 0xFFFFFFFF, buffer); yPos += ROW_HEIGHT; } client.udpSock_.Resend(); // check for messages from server NetworkMessage netMsg; if(client.udpSock_.Receive(netMsg)) ProcMessage(netMsg); #if 0 // =============== // update physics // =============== for (u32 i = 0; i < GAME_OBJ_INST_NUM_MAX; i++) { GameObjInst* pInst = sGameObjInstList + i; // skip non-active object if ((pInst->flag & FLAG_ACTIVE) == 0) continue; // update the position AEVec2ScaleAdd(&pInst->posCurr, &pInst->velCurr, &pInst->posCurr, (f32)(gAEFrameTime)); } // =============== // update objects // =============== for (u32 i = 0; i < GAME_OBJ_INST_NUM_MAX; i++) { GameObjInst* pInst = sGameObjInstList + i; // skip non-active object if ((pInst->flag & FLAG_ACTIVE) == 0) continue; // check if the object is a ship if (pInst->pObject->type == TYPE_SHIP) { // warp the ship from one end of the screen to the other pInst->posCurr.x = AEWrap(pInst->posCurr.x, gAEWinMinX - SHIP_SIZE, gAEWinMaxX + SHIP_SIZE); pInst->posCurr.y = AEWrap(pInst->posCurr.y, gAEWinMinY - SHIP_SIZE, gAEWinMaxY + SHIP_SIZE); } // check if the object is an asteroid else if (pInst->pObject->type == TYPE_ASTEROID) { AEVec2 u; f32 uLen; // warp the asteroid from one end of the screen to the other pInst->posCurr.x = AEWrap(pInst->posCurr.x, gAEWinMinX - AST_SIZE_MAX, gAEWinMaxX + AST_SIZE_MAX); pInst->posCurr.y = AEWrap(pInst->posCurr.y, gAEWinMinY - AST_SIZE_MAX, gAEWinMaxY + AST_SIZE_MAX); // pull the asteroid toward the ship a little bit if (spShip) { // apply acceleration propotional to the distance from the asteroid to the ship AEVec2Sub (&u, &spShip->posCurr, &pInst->posCurr); AEVec2Scale (&u, &u, AST_TO_SHIP_ACC * (f32)(gAEFrameTime)); AEVec2Add (&pInst->velCurr, &pInst->velCurr, &u); } // if the asterid velocity is more than its maximum velocity, reduce its speed if ((uLen = AEVec2Length(&pInst->velCurr)) > (AST_VEL_MAX * 2.0f)) { AEVec2Scale (&u, &pInst->velCurr, (1.0f / uLen) * (AST_VEL_MAX * 2.0f - uLen) * pow(AST_VEL_DAMP, (f32)(gAEFrameTime))); AEVec2Add (&pInst->velCurr, &pInst->velCurr, &u); } } // check if the object is a bullet else if (pInst->pObject->type == TYPE_BULLET) { // kill the bullet if it gets out of the screen if (!AEInRange(pInst->posCurr.x, gAEWinMinX - AST_SIZE_MAX, gAEWinMaxX + AST_SIZE_MAX) || !AEInRange(pInst->posCurr.y, gAEWinMinY - AST_SIZE_MAX, gAEWinMaxY + AST_SIZE_MAX)) gameObjInstDestroy(pInst); } // check if the object is a bomb else if (pInst->pObject->type == TYPE_BOMB) { // adjust the life counter pInst->life -= (f32)(gAEFrameTime) / BOMB_LIFE; if (pInst->life < 0.0f) { gameObjInstDestroy(pInst); } else { f32 radius = 1.0f - pInst->life; AEVec2 u; pInst->dirCurr += 2.0f * PI * (f32)(gAEFrameTime); radius = 1.0f - radius; radius *= radius; radius *= radius; radius *= radius; radius *= radius; radius = (1.0f - radius) * BOMB_RADIUS; // generate the particle ring for (u32 j = 0; j < 10; j++) { //f32 dir = AERandFloat() * 2.0f * PI; f32 dir = (j / 9.0f) * 2.0f * PI + pInst->life * 1.5f * 2.0f * PI; u.x = AECos(dir) * radius + pInst->posCurr.x; u.y = AESin(dir) * radius + pInst->posCurr.y; //sparkCreate(PTCL_EXHAUST, &u, 1, dir + 0.8f * PI, dir + 0.9f * PI); sparkCreate(PTCL_EXHAUST, &u, 1, dir + 0.40f * PI, dir + 0.60f * PI); } } } // check if the object is a missile else if (pInst->pObject->type == TYPE_MISSILE) { // adjust the life counter pInst->life -= (f32)(gAEFrameTime) / MISSILE_LIFE; if (pInst->life < 0.0f) { gameObjInstDestroy(pInst); } else { AEVec2 dir; if (pInst->pUserData == 0) { pInst->pUserData = missileAcquireTarget(pInst); } else { GameObjInst* pTarget = (GameObjInst*)(pInst->pUserData); // if the target is no longer valid, reacquire if (((pTarget->flag & FLAG_ACTIVE) == 0) || (pTarget->pObject->type != TYPE_ASTEROID)) pInst->pUserData = missileAcquireTarget(pInst); } if (pInst->pUserData) { GameObjInst* pTarget = (GameObjInst*)(pInst->pUserData); AEVec2 u; f32 uLen; // get the vector from the missile to the target and its length AEVec2Sub(&u, &pTarget->posCurr, &pInst->posCurr); uLen = AEVec2Length(&u); // if the missile is 'close' to target, do nothing if (uLen > 0.1f) { // normalize the vector from the missile to the target AEVec2Scale(&u, &u, 1.0f / uLen); // calculate the missile direction vector AEVec2Set(&dir, AECos(pInst->dirCurr), AESin(pInst->dirCurr)); // calculate the cos and sin of the angle between the target // vector and the missile direction vector f32 cosAngle = AEVec2DotProduct(&dir, &u), sinAngle = AEVec2CrossProductMag(&dir, &u), rotAngle; // calculate how much to rotate the missile if (cosAngle < AECos(MISSILE_TURN_SPEED * (f32)(gAEFrameTime))) rotAngle = MISSILE_TURN_SPEED * (f32)(gAEFrameTime); else rotAngle = AEACos(AEClamp(cosAngle, -1.0f, 1.0f)); // rotate to the left if sine of the angle is positive and vice versa pInst->dirCurr += (sinAngle > 0.0f) ? rotAngle : -rotAngle; } } // adjust the missile velocity AEVec2Set (&dir, AECos(pInst->dirCurr), AESin(pInst->dirCurr)); AEVec2Scale(&dir, &dir, MISSILE_ACCEL * (f32)(gAEFrameTime)); AEVec2Add (&pInst->velCurr, &pInst->velCurr, &dir); AEVec2Scale(&pInst->velCurr, &pInst->velCurr, pow(MISSILE_DAMP, (f32)(gAEFrameTime))); sparkCreate(PTCL_EXHAUST, &pInst->posCurr, 1, pInst->dirCurr + 0.8f * PI, pInst->dirCurr + 1.2f * PI); } } // check if the object is a particle else if ((TYPE_PTCL_WHITE <= pInst->pObject->type) && (pInst->pObject->type <= TYPE_PTCL_RED)) { pInst->scale *= pow(PTCL_SCALE_DAMP, (f32)(gAEFrameTime)); pInst->dirCurr += 0.1f; AEVec2Scale(&pInst->velCurr, &pInst->velCurr, pow(PTCL_VEL_DAMP, (f32)(gAEFrameTime))); if (pInst->scale < PTCL_SCALE_DAMP) gameObjInstDestroy(pInst); } } // ==================== // check for collision // ==================== for (u32 i = 0; i < GAME_OBJ_INST_NUM_MAX; i++) { GameObjInst* pSrc = sGameObjInstList + i; // skip non-active object if ((pSrc->flag & FLAG_ACTIVE) == 0) continue; if ((pSrc->pObject->type == TYPE_BULLET) || (pSrc->pObject->type == TYPE_MISSILE)) { for (u32 j = 0; j < GAME_OBJ_INST_NUM_MAX; j++) { GameObjInst* pDst = sGameObjInstList + j; // skip no-active and non-asteroid object if (((pDst->flag & FLAG_ACTIVE) == 0) || (pDst->pObject->type != TYPE_ASTEROID)) continue; if (AETestPointToRect(&pSrc->posCurr, &pDst->posCurr, pDst->scale, pDst->scale) == false) continue; if (pDst->scale < AST_SIZE_MIN) { sparkCreate(PTCL_EXPLOSION_M, &pDst->posCurr, (u32)(pDst->scale * 10), pSrc->dirCurr - 0.05f * PI, pSrc->dirCurr + 0.05f * PI, pDst->scale); sScore++; if ((sScore % AST_SPECIAL_RATIO) == 0) sSpecialCtr++; if ((sScore % AST_SHIP_RATIO) == 0) sShipCtr++; if (sScore == sAstNum * 5) sAstNum = (sAstNum < AST_NUM_MAX) ? (sAstNum * 2) : sAstNum; // destroy the asteroid gameObjInstDestroy(pDst); } else { sparkCreate(PTCL_EXPLOSION_S, &pSrc->posCurr, 10, pSrc->dirCurr + 0.9f * PI, pSrc->dirCurr + 1.1f * PI); // impart some of the bullet/missile velocity to the asteroid AEVec2Scale(&pSrc->velCurr, &pSrc->velCurr, 0.01f * (1.0f - pDst->scale / AST_SIZE_MAX)); AEVec2Add (&pDst->velCurr, &pDst->velCurr, &pSrc->velCurr); // split the asteroid to 4 if ((pSrc->pObject->type == TYPE_MISSILE) || ((pDst->life -= 1.0f) < 0.0f)) astCreate(pDst); } // destroy the bullet gameObjInstDestroy(pSrc); break; } } else if (TYPE_BOMB == pSrc->pObject->type) { f32 radius = 1.0f - pSrc->life; pSrc->dirCurr += 2.0f * PI * (f32)(gAEFrameTime); radius = 1.0f - radius; radius *= radius; radius *= radius; radius *= radius; radius *= radius; radius *= radius; radius = (1.0f - radius) * BOMB_RADIUS; // check collision for (u32 j = 0; j < GAME_OBJ_INST_NUM_MAX; j++) { GameObjInst* pDst = sGameObjInstList + j; if (((pDst->flag & FLAG_ACTIVE) == 0) || (pDst->pObject->type != TYPE_ASTEROID)) continue; if (AECalcDistPointToRect(&pSrc->posCurr, &pDst->posCurr, pDst->scale, pDst->scale) > radius) continue; if (pDst->scale < AST_SIZE_MIN) { f32 dir = atan2f(pDst->posCurr.y - pSrc->posCurr.y, pDst->posCurr.x - pSrc->posCurr.x); gameObjInstDestroy(pDst); sparkCreate(PTCL_EXPLOSION_M, &pDst->posCurr, 20, dir + 0.4f * PI, dir + 0.45f * PI); sScore++; if ((sScore % AST_SPECIAL_RATIO) == 0) sSpecialCtr++; if ((sScore % AST_SHIP_RATIO) == 0) sShipCtr++; if (sScore == sAstNum * 5) sAstNum = (sAstNum < AST_NUM_MAX) ? (sAstNum * 2) : sAstNum; } else { // split the asteroid to 4 astCreate(pDst); } } } else if (pSrc->pObject->type == TYPE_ASTEROID) { for (u32 j = 0; j < GAME_OBJ_INST_NUM_MAX; j++) { GameObjInst* pDst = sGameObjInstList + j; f32 d; AEVec2 nrm, u; // skip no-active and non-asteroid object if ((pSrc == pDst) || ((pDst->flag & FLAG_ACTIVE) == 0) || (pDst->pObject->type != TYPE_ASTEROID)) continue; // check if the object rectangle overlap d = AECalcDistRectToRect( &pSrc->posCurr, pSrc->scale, pSrc->scale, &pDst->posCurr, pDst->scale, pDst->scale, &nrm); if (d >= 0.0f) continue; // adjust object position so that they do not overlap AEVec2Scale (&u, &nrm, d * 0.25f); AEVec2Sub (&pSrc->posCurr, &pSrc->posCurr, &u); AEVec2Add (&pDst->posCurr, &pDst->posCurr, &u); // calculate new object velocities resolveCollision(pSrc, pDst, &nrm); } } else if (pSrc->pObject->type == TYPE_SHIP) { for (u32 j = 0; j < GAME_OBJ_INST_NUM_MAX; j++) { GameObjInst* pDst = sGameObjInstList + j; // skip no-active and non-asteroid object if ((pSrc == pDst) || ((pDst->flag & FLAG_ACTIVE) == 0) || (pDst->pObject->type != TYPE_ASTEROID)) continue; // check if the object rectangle overlap if (AETestRectToRect( &pSrc->posCurr, pSrc->scale, pSrc->scale, &pDst->posCurr, pDst->scale, pDst->scale) == false) continue; // create the big explosion sparkCreate(PTCL_EXPLOSION_L, &pSrc->posCurr, 100, 0.0f, 2.0f * PI); // reset the ship position and direction AEVec2Zero(&spShip->posCurr); AEVec2Zero(&spShip->velCurr); spShip->dirCurr = 0.0f; sSpecialCtr = SHIP_SPECIAL_NUM; // destroy all asteroid near the ship so that you do not die as soon as the ship reappear for (u32 j = 0; j < GAME_OBJ_INST_NUM_MAX; j++) { GameObjInst* pInst = sGameObjInstList + j; AEVec2 u; // skip no-active and non-asteroid object if (((pInst->flag & FLAG_ACTIVE) == 0) || (pInst->pObject->type != TYPE_ASTEROID)) continue; AEVec2Sub(&u, &pInst->posCurr, &spShip->posCurr); if (AEVec2Length(&u) < (spShip->scale * 10.0f)) { sparkCreate (PTCL_EXPLOSION_M, &pInst->posCurr, 10, -PI, PI); gameObjInstDestroy(pInst); } } // reduce the ship counter sShipCtr--; // if counter is less than 0, game over if (sShipCtr < 0) { sGameStateChangeCtr = 2.0; gameObjInstDestroy(spShip); spShip = 0; } break; } } } #endif // ===================================== // calculate the matrix for all objects // ===================================== for (u32 i = 0; i < GAME_OBJ_INST_NUM_MAX; i++) { GameObjInst* pInst = sGameObjInstList + i; AEMtx33 m; // skip non-active object if ((pInst->flag & FLAG_ACTIVE) == 0) continue; AEMtx33Scale (&pInst->transform, pInst->scale, pInst->scale); AEMtx33Rot (&m, pInst->dirCurr); AEMtx33Concat (&pInst->transform, &m, &pInst->transform); AEMtx33Trans (&m, pInst->posCurr.x, pInst->posCurr.y); AEMtx33Concat (&pInst->transform, &m, &pInst->transform); } }