void vsDisplayList::ApplyOffset(const vsVector2D &offset) { vsAssert( !m_instanceParent, "Tried to apply an offset to an instanced display list!" ); vsTransform2D currentTransform; Rewind(); op *o = PopOp(); while(o) { if ( o->type == OpCode_VertexArray ) { vsVector3D pos; int count = o->data.GetUInt(); float *shuttle = (float *) o->data.p; for ( int i = 0; i < count; i++ ) { shuttle[0] += offset.x; shuttle[1] += offset.y; shuttle += 3; } } o = PopOp(); } }
struct vsDisplayList::Stats vsDisplayList::CalculateStats() { Stats s; s.drawCount = 0; s.vertexCount = 0; s.triangleCount = 0; Rewind(); op *o = PopOp(); while(o) { if ( o->type == OpCode_VertexArray ) { int count = o->data.GetUInt(); s.vertexCount += count; } else if ( o->type == OpCode_VertexBuffer ) { vsRenderBuffer *buffer = (vsRenderBuffer *)o->data.p; s.vertexCount += buffer->GetVector3DArraySize(); } else if ( o->type == OpCode_BindBuffer ) { vsVector3D pos; vsRenderBuffer *buffer = (vsRenderBuffer *)o->data.p; s.vertexCount += buffer->GetPositionCount(); } else if ( o->type == OpCode_TriangleListBuffer ) { vsRenderBuffer *buffer = (vsRenderBuffer *)o->data.p; s.triangleCount += buffer->GetIntArraySize() / 3; s.drawCount++; } else if ( o->type == OpCode_TriangleStripBuffer ) { vsRenderBuffer *buffer = (vsRenderBuffer *)o->data.p; s.triangleCount += buffer->GetIntArraySize() - 2; s.drawCount++; } o = PopOp(); } return s; }
void vsDisplayList::GetBoundingCircle(vsVector2D ¢er, float &radius) { if ( m_instanceParent ) { m_instanceParent->GetBoundingCircle(center, radius); } else { vsVector3D min(1000000.0f,1000000.0f,1000000.f); vsVector3D max(-1000000.0f, -1000000.0f,-1000000.f); vsTransform2D currentTransform; Rewind(); op *o = PopOp(); while(o) { if ( o->type == OpCode_VertexArray ) { vsVector3D pos; int count = o->data.GetUInt(); float *shuttle = (float *) o->data.p; for ( int i = 0; i < count; i++ ) { pos.Set(shuttle[0],shuttle[1],shuttle[2]); max.x = vsMax( max.x, pos.x ); max.y = vsMax( max.y, pos.y ); max.z = vsMax( max.z, pos.z ); min.x = vsMin( min.x, pos.x ); min.y = vsMin( min.y, pos.y ); min.z = vsMin( min.z, pos.z ); shuttle += 3; } } o = PopOp(); } center = 0.5f * (max + min); radius = (max-min).Length() * 0.5f; } }
int vsDisplayList::GetTriangles(vsArray<struct Triangle>& result) { int count = 0; if ( m_instanceParent ) { return m_instanceParent->GetTriangles(result); } else { vsMatrix4x4 transformStack[20]; transformStack[0] = vsMatrix4x4::Identity; int transformStackLevel = 0; vsVector3D *currentVertexArray = NULL; vsRenderBuffer *currentVertexBuffer = NULL; //int currentVertexArraySize = 0; Rewind(); op *o = PopOp(); while(o) { if ( o->type == OpCode_PushMatrix4x4 ) { transformStack[transformStackLevel+1] = transformStack[transformStackLevel] * o->data.matrix4x4; transformStackLevel++; } if ( o->type == OpCode_SetMatrix4x4 ) { transformStack[++transformStackLevel] = o->data.matrix4x4; } else if ( o->type == OpCode_SetMatrices4x4 ) { vsMatrix4x4 *mat = (vsMatrix4x4*)o->data.p; transformStack[++transformStackLevel] = *mat; } else if ( o->type == OpCode_PopTransform ) { transformStackLevel--; } else if ( o->type == OpCode_VertexArray ) { vsVector3D pos; float *shuttle = (float *) o->data.p; currentVertexArray = (vsVector3D *)shuttle; currentVertexBuffer = NULL; } else if ( o->type == OpCode_VertexBuffer ) { vsVector3D pos; vsRenderBuffer *buffer = (vsRenderBuffer *)o->data.p; currentVertexArray = buffer->GetVector3DArray(); currentVertexBuffer = NULL; } else if ( o->type == OpCode_BindBuffer ) { vsVector3D pos; vsRenderBuffer *buffer = (vsRenderBuffer *)o->data.p; currentVertexArray = NULL;//buffer->GetVector3DArray(); currentVertexBuffer = buffer; } else if ( o->type == OpCode_TriangleListBuffer ) { vsRenderBuffer *buffer = (vsRenderBuffer *)o->data.p; uint16_t *shuttle = buffer->GetIntArray(); for ( int i = 0; i < buffer->GetIntArraySize(); i+=3 ) { uint16_t index0 = shuttle[i]; uint16_t index1 = shuttle[i+1]; uint16_t index2 = shuttle[i+2]; Triangle t; if ( currentVertexArray ) { t.vert[0] = transformStack[transformStackLevel].ApplyTo( currentVertexArray[index0] ); t.vert[1] = transformStack[transformStackLevel].ApplyTo( currentVertexArray[index1] ); t.vert[2] = transformStack[transformStackLevel].ApplyTo( currentVertexArray[index2] ); } else if ( currentVertexBuffer ) { t.vert[0] = transformStack[transformStackLevel].ApplyTo( currentVertexBuffer->GetPosition(index0) ); t.vert[1] = transformStack[transformStackLevel].ApplyTo( currentVertexBuffer->GetPosition(index1) ); t.vert[2] = transformStack[transformStackLevel].ApplyTo( currentVertexBuffer->GetPosition(index2) ); } else break; result.AddItem(t); count++; } } else if ( o->type == OpCode_TriangleStripBuffer ) { vsRenderBuffer *buffer = (vsRenderBuffer *)o->data.p; uint16_t *shuttle = buffer->GetIntArray(); for ( int i = 2; i < buffer->GetIntArraySize(); i++ ) { uint16_t index0 = shuttle[i-2]; uint16_t index1 = shuttle[i-1]; uint16_t index2 = shuttle[i]; Triangle t; if ( currentVertexArray ) { t.vert[0] = transformStack[transformStackLevel].ApplyTo( currentVertexArray[index0] ); t.vert[1] = transformStack[transformStackLevel].ApplyTo( currentVertexArray[index1] ); t.vert[2] = transformStack[transformStackLevel].ApplyTo( currentVertexArray[index2] ); } else if ( currentVertexBuffer ) { t.vert[0] = transformStack[transformStackLevel].ApplyTo( currentVertexBuffer->GetPosition(index0) ); t.vert[1] = transformStack[transformStackLevel].ApplyTo( currentVertexBuffer->GetPosition(index1) ); t.vert[2] = transformStack[transformStackLevel].ApplyTo( currentVertexBuffer->GetPosition(index2) ); } else break; result.AddItem(t); count++; } } o = PopOp(); } } return count; }
void vsDisplayList::GetBoundingBox( vsBox3D &box ) { box = vsBox3D(); if ( m_instanceParent ) { return m_instanceParent->GetBoundingBox(box); } else { vsMatrix4x4 transformStack[20]; transformStack[0] = vsMatrix4x4::Identity; int transformStackLevel = 0; vsVector3D *currentVertexArray = NULL; //int currentVertexArraySize = 0; Rewind(); op *o = PopOp(); while(o) { if ( o->type == OpCode_PushMatrix4x4 ) { transformStack[transformStackLevel+1] = transformStack[transformStackLevel] * o->data.matrix4x4; transformStackLevel++; } if ( o->type == OpCode_SetMatrix4x4 ) { transformStack[++transformStackLevel] = o->data.matrix4x4; } else if ( o->type == OpCode_SetMatrices4x4 ) { vsMatrix4x4 *mat = (vsMatrix4x4*)o->data.p; transformStack[++transformStackLevel] = *mat; } else if ( o->type == OpCode_PopTransform ) { transformStackLevel--; } else if ( o->type == OpCode_VertexArray ) { vsVector3D pos; int count = o->data.GetUInt(); float *shuttle = (float *) o->data.p; currentVertexArray = (vsVector3D *)shuttle; //currentVertexArraySize = count*3; for ( int i = 0; i < count; i++ ) { pos.Set(shuttle[0],shuttle[1],shuttle[2]); pos = transformStack[transformStackLevel].ApplyTo( pos ); box.ExpandToInclude( pos ); shuttle += 3; } } else if ( o->type == OpCode_VertexBuffer ) { vsVector3D pos; vsRenderBuffer *buffer = (vsRenderBuffer *)o->data.p; currentVertexArray = buffer->GetVector3DArray(); //currentVertexArraySize = buffer->GetVector3DArraySize(); for ( int i = 0; i < buffer->GetVector3DArraySize(); i++ ) { pos = buffer->GetVector3DArray()[i]; pos = transformStack[transformStackLevel].ApplyTo( pos ); box.ExpandToInclude( pos ); } } else if ( o->type == OpCode_BindBuffer ) { vsVector3D pos; vsRenderBuffer *buffer = (vsRenderBuffer *)o->data.p; int positionCount = buffer->GetPositionCount(); for ( int i = 0; i < positionCount; i++ ) { pos = buffer->GetPosition(i); pos = transformStack[transformStackLevel].ApplyTo( pos ); box.ExpandToInclude( pos ); } } else if ( o->type == OpCode_LineListBuffer || o->type == OpCode_LineStripBuffer ) { vsRenderBuffer *buffer = (vsRenderBuffer *)o->data.p; uint16_t *shuttle = buffer->GetIntArray(); for ( int i = 0; i < buffer->GetIntArraySize(); i++ ) { uint16_t index = shuttle[i]; box.ExpandToInclude( transformStack[transformStackLevel].ApplyTo( currentVertexArray[index] ) ); } } else if ( o->type == OpCode_LineStripArray ) { uint16_t *shuttle = (uint16_t *)o->data.p; int count = o->data.GetUInt(); for ( int i = 0; i < count; i++ ) { uint16_t index = shuttle[i]; box.ExpandToInclude( transformStack[transformStackLevel].ApplyTo( currentVertexArray[index] ) ); } } o = PopOp(); } } }
void vsDisplayList::GetBoundingBox( vsVector2D &topLeft, vsVector2D &bottomRight ) { vsBox2D box; topLeft.Set(500000.f,500000.f); bottomRight.Set(-50000.f,-50000.f); if ( m_instanceParent ) { return m_instanceParent->GetBoundingBox(topLeft, bottomRight); } else { vsTransform2D transformStack[20]; transformStack[0] = vsTransform2D::Zero; int transformStackLevel = 0; vsVector3D *currentVertexArray = NULL; vsRenderBuffer *currentVertexBuffer = NULL; Rewind(); op *o = PopOp(); while(o) { switch( o->type ) { case OpCode_SnapMatrix: // TODO: We can't really snap here; we don't know that we have a full transform stack. transformStack[transformStackLevel+1] = transformStack[transformStackLevel]; transformStackLevel++; break; case OpCode_PushTransform: transformStack[transformStackLevel+1] = transformStack[transformStackLevel] * o->data.transform; transformStackLevel++; break; case OpCode_PushTranslation: { vsTransform2D transform; transform.SetTranslation( o->data.GetVector3D() ); transformStack[transformStackLevel+1] = transformStack[transformStackLevel] * transform; transformStackLevel++; break; } case OpCode_PopTransform: transformStackLevel--; vsAssert(transformStackLevel >= 0, "Transform stack underflow while building bounding box"); break; case OpCode_VertexArray: currentVertexBuffer = NULL; currentVertexArray = (vsVector3D *)o->data.p; break; case OpCode_VertexBuffer: case OpCode_BindBuffer: currentVertexArray = NULL; currentVertexBuffer = (vsRenderBuffer *)o->data.p; break; case OpCode_LineListBuffer: case OpCode_LineStripBuffer: case OpCode_TriangleListBuffer: case OpCode_TriangleStripBuffer: case OpCode_TriangleFanBuffer: { vsRenderBuffer *buffer = (vsRenderBuffer *)o->data.p; uint16_t *shuttle = buffer->GetIntArray(); for ( int i = 0; i < buffer->GetIntArraySize(); i++ ) { uint16_t index = shuttle[i]; vsVector3D pos; if ( currentVertexArray ) pos = currentVertexArray[index]; else pos = currentVertexBuffer->GetPosition(index); box.ExpandToInclude( transformStack[transformStackLevel].ApplyTo(pos) ); } break; } case OpCode_LineListArray: case OpCode_LineStripArray: case OpCode_TriangleListArray: case OpCode_TriangleStripArray: case OpCode_TriangleFanArray: case OpCode_PointsArray: { uint16_t *shuttle = (uint16_t *)o->data.p; int count = o->data.GetUInt(); for ( int i = 0; i < count; i++ ) { uint16_t index = shuttle[i]; vsVector3D pos; if ( currentVertexArray ) pos = currentVertexArray[index]; else pos = currentVertexBuffer->GetPosition(index); box.ExpandToInclude( transformStack[transformStackLevel].ApplyTo(pos) ); } break; } default: break; } o = PopOp(); } } topLeft = box.GetMin(); bottomRight = box.GetMax(); }
/* Two operand functions for infix calc */ void twoop(int keynum) { if (flagINV) { flagINV=0; DrawDisplay(); } if (!entered) { /* something like "5+*" */ if (!isopempty()) (void) PopOp(); /* replace the prev op */ PushOp(keynum); /* with the new one */ return; } if (entered==1) parse_double(&dnum); clrdisp=CLR=1; entered=Dpoint=exponent=0; if (!isopempty()) { /* there was a previous op */ lastop=PopOp(); /* get it */ if (lastop==kLPAR) { /* put it back */ PushOp(kLPAR); PushOp(keynum); PushNum(dnum); return; } /* now, if the current op (keynum) is of higher priority than the lastop, the current op and number are just pushed on top Priorities: (Y^X) > *,/ > +,- > >>,<< > & > ^ > ~ */ if (priority(keynum) > priority(lastop)) { PushNum(dnum); PushOp(lastop); PushOp(keynum); } else { /* execute lastop on lastnum and dnum, push result and current op on stack */ acc=PopNum(); switch (lastop) { /* perform the operation */ case kADD: acc += dnum; break; case kSUB: acc -= dnum; break; case kMUL: acc *= dnum; break; case kDIV: acc /= dnum; break; case kPOW: acc = pow(acc,dnum); break; case kMOD: acc = (long)acc % (long)dnum; break; case kAND: acc = (long)acc & (long)dnum; break; case kOR: acc = (long)acc | (long)dnum; break; case kXOR: acc = (long)acc ^ (long)dnum; break; case kSHL: acc = (long)acc << (long)dnum; break; case kSHR: acc = (long)acc >> (long)dnum; break; } PushNum(acc); PushOp(keynum); format_double(acc); DrawDisplay(); dnum=acc; } }