- initial import
git-svn-id: http://moon:8086/svn/mips@1 a8ebac50-d88d-4704-bea3-6648445a41b3
This commit is contained in:
+412
@@ -0,0 +1,412 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "ri.h"
|
||||
#include "types.h"
|
||||
#include "matrix.h"
|
||||
#include "linklist.h"
|
||||
#include "vars.h"
|
||||
#include "grid.h"
|
||||
#include "graph_state.h"
|
||||
#include "object.h"
|
||||
|
||||
void Grid_create(grid_t *pObj, UINT32 npu, UINT32 npv)
|
||||
{
|
||||
UINT32 i, j, k, nu, nv;
|
||||
ri_var_t *pVar;
|
||||
|
||||
nu = npu + 1;
|
||||
nv = npv + 1;
|
||||
|
||||
pObj->nu = nu;
|
||||
pObj->nv = nv;
|
||||
pObj->npoints = nu*nv;
|
||||
|
||||
VarListInit(&pObj->vars);
|
||||
|
||||
pObj->pPointPos = (pixelpos_t*)malloc(nu*nv*sizeof(pixelpos_t));
|
||||
memset(pObj->pPointPos, 0, nu*nv*sizeof(pixelpos_t));
|
||||
|
||||
pObj->pPointState = (point_state_t*)malloc(nu*nv*sizeof(point_state_t));
|
||||
memset(pObj->pPointState, 0, nu*nv*sizeof(point_state_t));
|
||||
|
||||
k=0;
|
||||
for (i=0; i < nv; i++)
|
||||
{
|
||||
for (j=0; j < nu; j++)
|
||||
{
|
||||
pObj->pPointPos[k][0] = j;
|
||||
pObj->pPointPos[k][1] = i;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
for (i=0; i < (nv-1)*nu; i += nu)
|
||||
{
|
||||
for (j=0; j < nu-1; j++)
|
||||
{
|
||||
pObj->pPointState[i+j].has_face = 1;
|
||||
}
|
||||
}
|
||||
for (i=0; i < pObj->npoints; i ++)
|
||||
{
|
||||
pObj->pPointState[i].visible = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Grid_free(grid_t *pObj)
|
||||
{
|
||||
if (pObj->pPointPos)
|
||||
free(pObj->pPointPos);
|
||||
|
||||
if (pObj->pPointState)
|
||||
free(pObj->pPointState);
|
||||
|
||||
// VarListDelByName(&pObj->vars, "P");
|
||||
// VarListPrint(&pObj->vars);
|
||||
VarListFree(&pObj->vars);
|
||||
|
||||
}
|
||||
|
||||
void Grid_CopyVarByName(grid_t *pObj, RtToken pDstName, RtToken pSrcName)
|
||||
{
|
||||
ri_var_t *pSrc, *pDst;
|
||||
RtPointer pSrcData, pDstData;
|
||||
|
||||
pSrc = VarListFindByName(&pObj->vars, pSrcName);
|
||||
pDst = VarListFindByName(&pObj->vars, pDstName);
|
||||
|
||||
if (pDst)
|
||||
{
|
||||
if (pSrc->etype != pDst->etype)
|
||||
{
|
||||
fprintf(stderr, "Grid_CopyVar(): Variables are not of same type!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (pSrc->nvalues != pDst->nvalues)
|
||||
{
|
||||
fprintf(stderr, "Grid_CopyVar(): Variables are not of same size!\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pDst = VarListDeclare(&pObj->vars, pDstName, pSrc->cls, pSrc->type);
|
||||
VarAlloc(pDst, pSrc->nvalues);
|
||||
}
|
||||
|
||||
pSrcData = VarGet(pSrc);
|
||||
pDstData = VarGet(pDst);
|
||||
|
||||
memcpy(pDstData, pSrcData, pSrc->value_size*pSrc->nvalues);
|
||||
|
||||
}
|
||||
|
||||
void Grid_InitUV(grid_t *pObj)
|
||||
{
|
||||
UINT32 i, j, k, nu, nv;
|
||||
RtFloat *pU, *pV, u, v, du, dv;
|
||||
ri_var_t *pVar;
|
||||
|
||||
nu = pObj->nu;
|
||||
nv = pObj->nv;
|
||||
du = (RtFloat)1/(nu-1);
|
||||
dv = (RtFloat)1/(nv-1);
|
||||
|
||||
pVar = VarListDeclare(&pObj->vars, "u", "varying", "float");
|
||||
pU = (RtFloat*)VarAlloc(pVar, nu*nv);
|
||||
|
||||
pVar = VarListDeclare(&pObj->vars, "v", "varying", "float");
|
||||
pV = (RtFloat*)VarAlloc(pVar, nu*nv);
|
||||
|
||||
pVar = VarListDeclare(&pObj->vars, "du", "uniform", "float");
|
||||
VarSet(pVar, (RtPointer)&du, 1);
|
||||
|
||||
pVar = VarListDeclare(&pObj->vars, "dv", "uniform", "float");
|
||||
VarSet(pVar, (RtPointer)&dv, 1);
|
||||
|
||||
// Init uv-coords
|
||||
k = 0;
|
||||
v = 0;
|
||||
for (i=0; i < nv; i++)
|
||||
{
|
||||
u = 0;
|
||||
for (j=0; j < nu; j++)
|
||||
{
|
||||
pU[k] = u;
|
||||
pV[k] = v;
|
||||
u += du;
|
||||
k++;
|
||||
}
|
||||
v += dv;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Grid_assign_derivs(grid_t *pObj)
|
||||
{
|
||||
UINT32 i, j, k, nu, nv;
|
||||
RtPoint *pPoint, *pDPDU, *pDPDV, dpd2;
|
||||
RtFloat du, dv, ik;
|
||||
ri_var_t *pVar;
|
||||
|
||||
nu = pObj->nu;
|
||||
nv = pObj->nv;
|
||||
|
||||
pPoint = (RtPoint*)VarGetByName(&pObj->vars, "P");
|
||||
du = *((RtFloat*)VarGetByName(&pObj->vars, "du"));
|
||||
dv = *((RtFloat*)VarGetByName(&pObj->vars, "dv"));
|
||||
|
||||
pDPDU = (RtPoint*)VarGetByName(&pObj->vars, "dpdu");
|
||||
if (!pDPDU)
|
||||
pDPDU = (RtPoint*)VarAlloc(VarListDeclare(&pObj->vars, "dpdu", "varying", "point"), pObj->npoints);
|
||||
|
||||
pDPDV = (RtPoint*)VarGetByName(&pObj->vars, "dpdv");
|
||||
if (!pDPDV)
|
||||
pDPDV = (RtPoint*)VarAlloc(VarListDeclare(&pObj->vars, "dpdv", "varying", "point"), pObj->npoints);
|
||||
|
||||
for (i=0; i < pObj->npoints; i += nu)
|
||||
{
|
||||
for (j=0; j < nu-1; j++)
|
||||
{
|
||||
ik = (RtFloat)1/du;
|
||||
for (k=0; k < 3; k++)
|
||||
{
|
||||
pDPDU[i+j][k] = ik*(pPoint[i+j+1][k] - pPoint[i+j][k]);
|
||||
}
|
||||
}
|
||||
for (k=0; k < 3; k++)
|
||||
{
|
||||
pDPDU[i+j][k] = 2*pDPDU[i+j-1][k] - pDPDU[i+j-2][k];
|
||||
}
|
||||
|
||||
}
|
||||
for (i=0; i < nu; i++)
|
||||
{
|
||||
for (j=0; j < (nv-1)*nu; j += nu)
|
||||
{
|
||||
ik = (RtFloat)1/dv;
|
||||
for (k=0; k < 3; k++)
|
||||
{
|
||||
pDPDV[i+j][k] = ik*(pPoint[i+j+nu][k] - pPoint[i+j][k]);
|
||||
}
|
||||
}
|
||||
for (k=0; k < 3; k++)
|
||||
{
|
||||
pDPDV[i+j][k] = 2*pDPDV[i+j-nu][k] - pDPDV[i+j-2*nu][k];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Grid_calc_normal(grid_t *pObj, RtToken name)
|
||||
{
|
||||
UINT32 i;
|
||||
RtFloat *a, *b;
|
||||
RtPoint *pPoint, *pDPDU, *pDPDV, *pN;
|
||||
|
||||
pDPDU = (RtPoint*)VarGetByName(&pObj->vars, "dpdu");
|
||||
pDPDV = (RtPoint*)VarGetByName(&pObj->vars, "dpdv");
|
||||
pN = (RtPoint*)VarGetByName(&pObj->vars, name);
|
||||
if (!pN)
|
||||
pN = (RtPoint*)VarAlloc(VarListDeclare(&pObj->vars, name, "varying", "point"), pObj->npoints);
|
||||
|
||||
for (i=0; i < pObj->npoints; i++)
|
||||
{
|
||||
a = pDPDU[i];
|
||||
b = pDPDV[i];
|
||||
pN[i][0] = a[1]*b[2] - a[2]*b[1];
|
||||
pN[i][1] = a[2]*b[0] - a[0]*b[2];
|
||||
pN[i][2] = a[0]*b[1] - a[1]*b[0];
|
||||
}
|
||||
}
|
||||
|
||||
void Grid_displace(grid_t *pObj)
|
||||
{
|
||||
UINT32 i, j, k;
|
||||
RtPoint *pP, *pDPDU, *pDPDV, *pN;
|
||||
RtColor *pCs, *pCi;
|
||||
RtFloat *pU, *pV, fd, kn, kd;
|
||||
|
||||
pP = (RtPoint*)VarGetByName(&pObj->vars, "P");
|
||||
pU = (RtFloat*)VarGetByName(&pObj->vars, "u");
|
||||
pV = (RtFloat*)VarGetByName(&pObj->vars, "v");
|
||||
pDPDU = (RtPoint*)VarGetByName(&pObj->vars, "dpdu");
|
||||
pDPDV = (RtPoint*)VarGetByName(&pObj->vars, "dpdv");
|
||||
pN = (RtPoint*)VarGetByName(&pObj->vars, "Ng");
|
||||
|
||||
kd = 0.00;
|
||||
for (i=0; i < pObj->npoints; i++)
|
||||
{
|
||||
|
||||
if (!pObj->pPointState[i].visible)
|
||||
continue;
|
||||
|
||||
kn = (RtFloat)1/Norm((RtFloat*)pN[i], 3);
|
||||
|
||||
fd = cos(10*3.141592654*pV[i]);
|
||||
pP[i][0] += kd*fd*pN[i][0]*kn;
|
||||
pP[i][1] += kd*fd*pN[i][1]*kn;
|
||||
pP[i][2] += kd*fd*pN[i][2]*kn;
|
||||
}
|
||||
Grid_assign_derivs(pObj);
|
||||
Grid_calc_normal(pObj, "Ng");
|
||||
|
||||
}
|
||||
|
||||
void Normalize(RtPoint N, RtPoint Nn)
|
||||
{
|
||||
RtFloat k;
|
||||
|
||||
k = (RtFloat)1/Norm((RtFloat*)N, 3);
|
||||
|
||||
Nn[0] = N[0]*k;
|
||||
Nn[1] = N[1]*k;
|
||||
Nn[2] = N[2]*k;
|
||||
|
||||
}
|
||||
|
||||
void Negate(RtPoint N, RtPoint Ni)
|
||||
{
|
||||
|
||||
Ni[0] = -N[0];
|
||||
Ni[1] = -N[1];
|
||||
Ni[2] = -N[2];
|
||||
|
||||
}
|
||||
|
||||
RtFloat* Diffuse(linkedlist_t *pLightList, RtPoint N, RtPoint P)
|
||||
{
|
||||
static RtFloat result[3];
|
||||
RtPoint L, Ln, Nn;
|
||||
linkedlist_t *pLights;
|
||||
object_t *pLight;
|
||||
RtFloat k, kn;
|
||||
|
||||
pLights = LinkedList_find_first(pLightList);
|
||||
|
||||
memset(result, 0, sizeof(RtColor));
|
||||
Normalize(N, Nn);
|
||||
|
||||
while(pLights)
|
||||
{
|
||||
pLight = (object_t*)LinkedList_get(pLights);
|
||||
L[0] = (*pLight->pXform)[0][3] - P[0];
|
||||
L[1] = (*pLight->pXform)[1][3] - P[1];
|
||||
L[2] = (*pLight->pXform)[2][3] - P[2];
|
||||
Normalize(L, Ln);
|
||||
k = MAX(ScalarProduct(Ln, Nn, 3), 0);
|
||||
|
||||
result[0] += pLight->pAttr->cs[0] * k;
|
||||
result[1] += pLight->pAttr->cs[1] * k;
|
||||
result[2] += pLight->pAttr->cs[2] * k;
|
||||
|
||||
pLights = pLights->pNext;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
RtFloat* Specular(linkedlist_t *pLightList, RtPoint N, RtPoint P, RtPoint I, RtFloat roughness)
|
||||
{
|
||||
static RtFloat result[3];
|
||||
RtPoint L, H, Hn, Ln, Nn, In, Ini;
|
||||
linkedlist_t *pLights;
|
||||
object_t *pLight;
|
||||
RtFloat k, kn;
|
||||
|
||||
pLights = LinkedList_find_first(pLightList);
|
||||
|
||||
memset(result, 0, sizeof(RtColor));
|
||||
Normalize(N, Nn);
|
||||
Normalize(I, In);
|
||||
Negate(In, Ini);
|
||||
|
||||
while(pLights)
|
||||
{
|
||||
pLight = (object_t*)LinkedList_get(pLights);
|
||||
L[0] = (*pLight->pXform)[0][3] - P[0];
|
||||
L[1] = (*pLight->pXform)[1][3] - P[1];
|
||||
L[2] = (*pLight->pXform)[2][3] - P[2];
|
||||
Normalize(L, Ln);
|
||||
H[0] = Ini[0] + Ln[0];
|
||||
H[1] = Ini[1] + Ln[1];
|
||||
H[2] = Ini[2] + Ln[2];
|
||||
Normalize(H, Hn);
|
||||
|
||||
k = pow(MAX(ScalarProduct(Nn, Hn, 3), 0), (RtFloat)1/roughness);
|
||||
|
||||
result[0] += pLight->pAttr->cs[0] * k;
|
||||
result[1] += pLight->pAttr->cs[1] * k;
|
||||
result[2] += pLight->pAttr->cs[2] * k;
|
||||
|
||||
pLights = pLights->pNext;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
void Grid_shade(grid_t *pObj, RtMatrix *pXform, linkedlist_t *pLights)
|
||||
{
|
||||
UINT32 i, j, k;
|
||||
RtPoint *pP, *pDPDU, *pDPDV, *pN, *pI;
|
||||
RtColor *pCs, *pCi;
|
||||
RtFloat *pU, *pV, fd, kn, vt, p[4], d[4], *pCl_diff, *pCl_spec;
|
||||
RtFloat kd, ks;
|
||||
|
||||
pP = (RtPoint*)VarGetByName(&pObj->vars, "P");
|
||||
pU = (RtFloat*)VarGetByName(&pObj->vars, "u");
|
||||
pV = (RtFloat*)VarGetByName(&pObj->vars, "v");
|
||||
pCs = (RtColor*)VarGetByName(&pObj->vars, "Cs");
|
||||
pDPDU = (RtPoint*)VarGetByName(&pObj->vars, "dpdu");
|
||||
pDPDV = (RtPoint*)VarGetByName(&pObj->vars, "dpdv");
|
||||
pN = (RtPoint*)VarGetByName(&pObj->vars, "Ng");
|
||||
pI = (RtPoint*)VarGetByName(&pObj->vars, "I");
|
||||
|
||||
pCi = (RtColor*)VarAlloc(VarListDeclare(&pObj->vars, "Ci", "varying", "color"), pObj->npoints);
|
||||
p[3] = (RtFloat)1.0;
|
||||
|
||||
kd = 1;
|
||||
ks = 0.4;
|
||||
|
||||
for (i=0; i < pObj->npoints; i++)
|
||||
{
|
||||
|
||||
if (!pObj->pPointState[i].visible)
|
||||
continue;
|
||||
|
||||
pCl_diff = Diffuse(pLights, pN[i], pP[i]);
|
||||
pCl_spec = Specular(pLights, pN[i], pP[i], pI[i], 0.01);
|
||||
|
||||
fd = (RtFloat)rand()/RAND_MAX;
|
||||
pCi[i][0] = (*pCs)[0]*(kd*pCl_diff[0]) + ks*pCl_spec[0];
|
||||
pCi[i][1] = (*pCs)[1]*(kd*pCl_diff[1]) + ks*pCl_spec[1];
|
||||
pCi[i][2] = (*pCs)[2]*(kd*pCl_diff[2]) + ks*pCl_spec[2];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Grid_shadeConstant(grid_t *pObj)
|
||||
{
|
||||
UINT32 i;
|
||||
RtColor *pCs, *pCi;
|
||||
|
||||
pCs = (RtColor*)VarGetByName(&pObj->vars, "Cs");
|
||||
pCi = (RtColor*)VarAlloc(VarListDeclare(&pObj->vars, "Ci", "varying", "color"), pObj->npoints);
|
||||
|
||||
for (i=0; i < pObj->npoints; i++)
|
||||
{
|
||||
|
||||
if (!pObj->pPointState[i].visible)
|
||||
continue;
|
||||
|
||||
|
||||
pCi[i][0] = (*pCs)[0];
|
||||
pCi[i][1] = (*pCs)[1];
|
||||
pCi[i][2] = (*pCs)[2];
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user